函数调用方式
1 作为函数
2 作为方法
3 作为构造函数
4 通过他们的call()和apply()调用
demo function:
function inherit( p) {
if ( p === null) {
throw TypeError()
}
if (Object.create) {
return Object.create(p)
}
const t = typeof p
if (t !== "object" && t !== "function") {
throw TypeError()
}
function f(){}
f.prototype = p
return f
}
作为函数调用
var first = {x:1}
var second = inherit(first)
根据ECMAScript3和非严格的ECMAScript5对函数调用的规定,调用上下文(this的值)是全局对象。在严格模式下,调用上下文是undefined。
以函数形式调用的函数,一般不使用this。
方法调用
方法:保存在对象属性里的函数。
方法调用和函数调用一个重要的区别:上下文。
上下文this指向对象。
demo:
var calculator = {
operand1: 1,
operand2: 1,
add: function() {
this.result = this.operand1 + this.operand2;
}
}
calculator.add()
calculator.result == 2
关键字this没有作用域,嵌套函数不会从调用它的函数中继承this。如果嵌套函数作为方法调用,this指向调用它的函数。如果嵌套函数作为函数调用,this要么指向全局对象(非严格模式),要么undefined(严格模式)。如果需要嵌套函数访问this,需要将this保存到一个变量里。
var o = {
m: function() {
var self = this
console.log(this === o)
f()
function f() {
console.log(this === o)//this 指向全局对象,或者undefined。
console.log(self === o)//相等
}
}
}
o.m()
构造函数
函数和方法调用之前有new关键字,就是构造函数调用。
如果构造函数有参数,则用括号。
如果构造函数没有参数,可以不带括号。
var o = new Object()
var o = new Object
构造函数创建一个新的空对象,继承自构造函数的prototype。
构造函数创建新对象,并将这个新对象作为this。
所以,new o.m()中的this不是指向o,而是m创建的新对象。
间接调用
call、 apply 、bind都是来重定义 this 这个对象。
call和apply类似,区别是入参的形式,如下:
o.m.call(o, 'param1', 'param2')
o.m.apply(o, ['param1', 'param2'])
bind是在ECMAScript5新加的方法,将函数绑定到某个对象。
function f(y){
return this.x + y
}
var o = {x:1}
var g = f.bind(o)
g(2) //o.f(2)
作为附带的功能,bind可以将参数绑定。
function f(x, y){
return x + y
}
var succ = f.bind(null, 1)
succ(2) // x:1,y:2, 返回1+2
function f(y,z) {
return this.x +y + z
}
var g = f.bind({x:1}, 2) // this.x:1, y:2
g(3) //z:3,结果为6