Object Type
创建Object实例
创建Object实例的方法有两种
Object构造函数
var person = new Object();
person.name = "Nicholas";
person.age = 29;
对象字面量
var person = {
name : "Nicholas", // 用逗号隔开各个属性
age : 29 // 此处无逗号
};
使用对象字面量时,属性名可以是字符串,如下
var person = {
"name" : "Nicholas",
"age" : 29,
5: true
};
此处name,age,5都会作为字符串处理
如下的定义方式也是正确的
var person = {}; //same as new Object()
person.name = "Nicholas";
person.age = 29;
通过对象字面量定义对象时,不会调用Object构造函数
另外,对象字面量也是向函数传递大量可选参数的首选方法
function displayInfo(args) {
var output = "";
if (typeof args.name == "string"){
output += "Name: " + args.name + "\n";
}
if (typeof args.age == "number") {
output += "Age: " + args.age + "\n";
}
alert(output);
}
displayInfo({
name: "Nicholas",
age: 29
});
displayInfo({
name: "Greg"
});
上面的代码中,我们先定义了一个displayInfo函数,然后两次调用该函数,两次调用所传递的参数都不同
上面的方式最适合传递若干可选参数的情形。
访问对象的属性
访问对象的属性可以有两种方式,除了点表示法,还可以使用方括号表示法。不过属性名应该以字符串的形式放在方括号中 如下
alert(person["name"]); //"Nicholas"
alert(person.name); //"Nicholas"
以上两种方法没有区别,但方括号语法的优点是可以通过变量的方式访问,如下
var propertyName = "name";
alert(person[propertyName]); //"Nicholas"
如果属性名中包含导致语法错误的字符,或者关键字,保留字,则可以使用方括号表示法,如下
person["first name"] = "Nicholas";
除了特别情况,一般推荐使用点表示法
Function Type
javascript中的函数也是对象,函数名是指向函数对象的指针,所以,javascript中的重载其实只是 函数名指向另一个函数而已。
定义函数可以有以下三种方式
using function-declaration syntax
function sum (num1, num2) {
return num1 + num2;
}
using a function expression
var sum = function(num1, num2){
return num1 + num2;
};
using the Function constructor
这种方式不推荐使用。这种语法能很好解释函数时一种对象。
var sum = new Function("num1", "num2", "return num1 + num2"); //not recommended
以上表达式中,Function的最后一个参数是函数体,其他为函数参数。
由于函数名只是函数对象的指针,那么一个函数可以有多个名字(一个函数对象可以有多个函数指针),如下
function sum(num1, num2){
return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20
No Overloading (没有重载)
看如下例子
function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100); //300
我们貌似对addSomeNumber(num)进行了重载,然后进行调用,最后调用到了第二个函数, 其实此处没有重载,下面代码等同于上面代码,
var addSomeNumber = function (num){
return num + 100;
};
addSomeNumber = function (num) {
return num + 200;
};
var result = addSomeNumber(100); //300
很明显,所谓的”重载”,只是函数对象被重新定义了而已,而非重载。
Function Declarations versus Function Expressions (函数声明和函数表达式)
如下代码
alert(sum(10,10));
function sum(num1, num2){
return num1 + num2;
}
函数sum声明在调用之后,但是能正常执行。
Function Declarations 与 Function Expressions 之间有一个区别,就是Function Declarations 中有函数声明提升(function declaration hoisting.) 在代码执行之前,解析器会将函数声明添加到执行环境,并放到源代码树的顶部。
再看如下代码,
alert(sum(10,10)); //unexpected identifi er
var sum = function(num1, num2){
return num1 + num2;
};
如上代码使用函数表达式,则会出错。
Functions as Values
函数作为值,可以作为值传入给某个函数,也可以作为某个函数的返回值 (This means it’s possible not only to pass a function into another function as an argument but also to return a function as the result of another function.)
pass a function into another function
function callSomeFunction(someFunction, someArgument){
return someFunction(someArgument);
}
function add10(num){
return num + 10;
}
var result1 = callSomeFunction(add10, 10);
alert(result1); //20
function getGreeting(name){
return "Hello, " + name;
}
var result2 = callSomeFunction(getGreeting, "Nicholas");
alert(result2); //"Hello, Nicholas"
上面代码定义函数callSomeFunction,它能接收2个参数,一个是某个函数指针x,一个是函数x的参数, 然后在callSomeFunction执行函数x 。
return a function as the result of another function
以下函数返回结果是一个函数,这个返回函数主要是对object1,object2两个对象的某个属性进行比较。 该函数常用于数组的排序
function createComparisonFunction(propertyName) {
return function(object1, object2){
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 < value2){
return -1;
} else if (value1 > value2){
return 1;
} else {
return 0;
}
};
}
var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];
data.sort(createComparisonFunction("name"));
alert(data[0].name); //Nicholas
data.sort(createComparisonFunction("age"));
alert(data[0].name); //Zachary
Function Internals (函数内部属性)
Two special objects exist inside a function: arguments and this。
arguments
arguments 对象代表传递给函数的参数数组,它也是一个对象,它有一个特殊的属性: callee callee此处其实也是个函数,但是在javascript中函数也是对象,所以此处也称为属性。 callee指向拥有arguments对象的对象( the arguments object also has a property named callee, which is a pointer to the function that owns the arguments object)
看如下递归例子
function factorial(num){
if (num <= 1) {
return 1;
} else {
return num * factorial(num-1)
}
}
当函数指针赋值给另一个变量时,上面函数内部与名字factorial耦合则会出现问题 为了解决这个问题,可以用如下方式
function factorial(num){
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num-1)
}
}
var trueFactorial = factorial;
factorial = function(){
return 0;
};
alert(trueFactorial(5)); //120
alert(factorial(5)); //0
this
某个全局环境中的函数,它的this指针等同于window 某个对象内部的函数的this,它指向这个对象本身。
如下:
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"
ECMAScript还规范化了另一个函数对象的属性:caller。它指向调用当前函数的函数的引用,如果当前函数时在全局作用域中, 则它的caller属性为null。如下代码:
function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer();
上述代码将在警告框显示outer()函数的源代码 为了实现更松散的耦合,可以如下
function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();
Function Properties and Methods
Each function has two properties: length and prototype .length属性返回函数的参数个数,prototype不在这里讲解。
function sayName(name){
alert(name);
}
function sum(num1, num2){
return num1 + num2;
}
function sayHi(){
alert("hi");
}
alert(sayName.length); //1
alert(sum.length); //2
alert(sayHi.length); //0
There are two additional methods for functions: apply() and call().
apply(),call()的基本作用都是调用函数,如下
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); //passing in arguments object
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); //passing in array
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
function sum(num1, num2){
return num1 + num2;
}
call()方法需要罗列出具体每个参数,apply()方法只需使用arguments。
function callSum(num1, num2){
return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20
apply(),call()最强大的作用并不在于传递参数,调用函数,而是扩充函数的作用域,如下
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
Running sayColor.call(o) switches the context of the function such that this points to o, resulting in a display of “blue”.
使用apply() , call() 扩大函数的作用域的好处是,对象与方法不需要有任何耦合关系。
ECMAScript 5 定义了一个bind()方法,The bind() method creates a new function instance whose this value is bound to the value that was passed into bind()
如下
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
另外
函数对象调用toLocaleString() toString() valueOf() 将返回函数代码