当函数调用时,接收两个附加的参数:this , arguments。
java中的对象无数个,都存在堆中,且有一个唯一的编号标识,所以当前对象的属性和方法前面必须加一个this,不然系统也无法区分到底属性和方法是谁的呢!
javascript里也一样:用this来表示当前对象。
1、 对象里的方法调用模式
方法:当一个函数作为一个对象的属性存储时. 当一个函数被调用时,this和那个对象绑定。
// Create myObject. It has a value and an increment method. The //increment method takes an optional parameter. // If the argument is not a number, then 1 is used as the default. var myObject = { value: 0, increment: function (inc) { this.value += typeof inc === 'number' ? inc : 1; } }; myObject.increment( ); //对象.方法() document.writeln(myObject.value); // 1 myObject.increment(2); document.writeln(myObject.value); // 3 |
一个方法能使用this表示当前对象,可以从对象中取出值,然后修改对象的值。this和对象绑定是在函数调用时,这种非常晚的绑定能使函数更高的使用。方法从this得到对象的context,叫公共方法。
2、The Function Invocation Pattern
当一个函数不是对象属性时,然后当成函数来调用,如下:
var add=function(a,b){
return a+b;
}
var sum = add(3, 4); // sum is 7
When a function is invoked with this pattern,thisis bound to the global object.
This was a mistake in the design of the language. Had the language been designed
correctly, when the inner function is invoked,
this would still be bound to the
this
variable of the outer function. A consequence of this error is that a method cannot
employ an inner function to help it do its work because the inner function does not
share the method’s access to the object as its
this is bound to the wrong value. Fortunately, there is an easy workaround. If the method defines a variable and assigns it
the value of this, the inner function will have access tothisthrough that
variable. By
convention, the name of that variable is
that:
// Augment myObject with a double method. myObject.double = function ( ) { var that = this; // Workaround. var helper = function ( ) { that.value = add(that.value, that.value); }; helper( ); // Invoke helper as a function. }; // Invoke double as a method. myObject.double( ); document.writeln(myObject.value); |
3、构造函数调用模式,用new实例化,然后调用get_status()函数。
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status( )); // confused
JavaScript 是一个 prototypal 继承语言.
这意味着对象能直接继承其它对象的属性。The language is class-free.
This is a radical departure from the current fashion. Most languages today areclassical. Prototypal inheritance is powerfully expressive, but is not widely understood.
JavaScript 本身 is not confident in its prototypal nature, so it offers an object-making
syntax that is reminiscent of the classical languages. Few classical programmers
found prototypal inheritance to be acceptable, and classically inspired syntax
obscures the language’s true prototypal nature. It is the worst of both worlds.
If a function is invoked with the
new prefix, then a new object will be created with a
hidden link to the value of the function’s
prototype member, and
this will be bound
to that new object.
The new
prefix also changes the behavior of the
return statement. We will see more
about that next.
// 建立一个名叫Quo的构造函数,有一个status 属性。 var Quo = function (string) { this.status = string; }; // 给所有Quo实例一个公共方法get_status(). Quo.prototype.get_status = function ( ) { return this.status; }; // 建立Quo的一个实例. var myQuo = new Quo("confused"); document.writeln(myQuo.get_status( )); // confused |
convention, they are kept in variables with a capitalized name. If a constructor is
called without the new prefix, very bad things can happen without a compile-time or
runtime warning, so the capitalization convention is really important.
Use of this style of constructor functions is not recommended. We will see better
alternatives in the next chapter.
4、 The Apply Invocation Pattern
Because JavaScript is a functional object-oriented language, functions can have
methods.
The apply
method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value ofthis. Theapplymethod
takes two parameters. The first is the value that should be bound tothis. The second is an array of parameters.
// Make an array of 2 numbers and add them. var add=function(a,b){ return a+b; } var array = [3, 4]; var sum = add.apply(null, array); // sum is 7 // Make an object with a status member. var statusObject = { status: 'A-OK' }; // statusObject does not inherit from Quo.prototype, // but we can invoke the get_status method on // statusObject even though statusObject does not have // a get_status method. var status = Quo.prototype.get_status.apply(statusObject); // status is 'A-OK' |
参考:the good part