在本文中,我们将了解什么是JavaScript中的this
关键字,this
关键字的四种不同绑定以及“ new”关键字。
this
关键字是指一个对象,该对象正在执行javascript代码的当前位。
换句话说,每个javascript函数在执行时都会引用其当前执行上下文,称为this。执行上下文意味着这里是函数的调用方式。
要理解this
关键字,只需要知道如何,何时何地从何处调用该函数,与如何声明和定义函数以及在何处定义无关紧要
function bike() {
console.log(this.name);
}
var name = "Ninja";
var obj1 = { name: "Pulsar", bike: bike };
var obj2 = { name: "Gixxer", bike: bike };
bike(); // "Ninja"
obj1.bike(); // "Pulsar"
obj2.bike(); // "Gixxer"
在上面的代码片段中,bike()
函数的工作是打印console.log
,this.name
这意味着它正在尝试打印name当前执行上下文(即this object)的property的值。
在上面的代码片段中,当函数bike()
被调用时它会打印,“Ninja” 因为未指定执行上下文,因此默认情况下它是全局上下文,并且在全局上下文中存在一个变量name,其值为“Ninja”。
在情况下obj1().bike()
,“Pulsar”被打印, 这背后的原因是函数bike()被调用执行上下文obj1, 这样this.name
成了obj1.name。同样的,obj2.bike()这里的函数执行上下文bike()是obj2。
默认和隐式绑定this
- 如果我们
strict
模式,则默认值this关键字undefined
,否则this关键字充当全局对象,这就是所谓的默认绑定this关键字。(对于浏览器,默认为窗口对象)。 - 当有一个对象属性作为方法被调用时,该对象成为该方法的
this
对象或执行上下文对象,它是this关键字的隐式绑定。
var obj1 = {
name: "Pulsar",
bike: function() {
console.log(this.name);
}
}
var obj2 = { name: "Gixxer", bike: obj1.bike };
var name = "Ninja";
var bike = obj1.bike;
bike(); // "Ninja"
obj1.bike(); // "Pulsar"
obj2.bike(); // "Gixxer"
在上面的代码片段中,函数调用bike()是默认绑定的示例。obj1.bike()并且obj2.bike()是隐式绑定的示例。这里bike函数声明为的一部分obj1,但无论是当我们执行obj2.bike(),执行的背景下obj2使obj2.name被打印出来。
重要的是要知道如何,何时何地调用函数与声明函数的位置无关。
“ this”关键字的显式和固定绑定
如果我们在调用函数中使用call和apply方法,则这两个方法均将其第一个参数作为执行上下文。那具有this约束力。
function bike() {
console.log(this.name);
}
var name = "Ninja";
var obj = { name: "Pulsar" }
bike(); // "Ninja"
bike.call(obj); // "Pulsar"
在该上述代码段中,如果我们调用函数bike与call()方法通过执行上下文对象obj作为第一个参数,然后obj被分配到this对象,并将其打印“Pulsar”这只不过是obj.name。这称为this关键字的显式绑定。
- 在固定绑定或硬绑定中,this无论从何处以及如何调用它,我们都可以强制对象始终相同。
var bike = function() {
console.log(this.name);
}
var name = "Ninja";
var obj1 = { name: "Pulsar" };
var obj2 = { name: "Gixxer" };
var originalBikeFun = bike;
bike = function() {
originalBikeFun.call(obj1);
};
bike(); // "Pulsar"
bike.call(obj2); // "Pulsar"
按照上面的代码片段,bike()并bike.call(obj2)能打印"Pulsar"这无非是obj1.name指函数的执行上下文bike总是OBJ1和其因为originalBikeFun.call(obj1); 这些种类的this结合是明确的结合称为固定的结合只是另一种味道。
JavaScript中的“ new”关键字
任何函数前面的new关键字都会将函数调用转换为构造函数调用,并且在new关键字放在函数前面时会发生以下情况
- 创建了一个全新的空对象
- 新的空对象链接到该函数的原型属性
- 相同的新空对象被绑定为函数调用执行上下文的
this
- 如果该函数不返回任何内容,则它隐式返回
this
对象。
function bike() {
var name = "Ninja";
this.maker = "Kawasaki";
console.log(this.name + " " + maker); // undefined Bajaj
}
var name = "Pulsar";
var maker = "Bajaj";
obj = new bike();
console.log(obj.maker); // "Kawasaki"
在上面的代码片段中,bike函数new在其前面用关键字调用。因此,它将创建一个新对象,然后将新对象链接到函数原型链bike,然后将创建的新对象绑定到this对象,然后函数返回this对象。这就是将返回的this对象分配给objand console.log(obj.maker)打印“Kawasaki”。
在上面的代码片段,this.name里面的功能bike()不打印“Ninja”或“Pulsar”代替它打印undefined,因为name变量的函数内声明bike()和this.name 是完全两个不同的东西。内部函数相同this.maker而maker不同bike()。
this
关键字绑定的优先级
- 首先,它检查是否使用new关键字调用该函数。
- 其次,它检查函数是使用call()调用还是apply()方法表示显式绑定。
- 第三,它检查该函数是否通过上下文对象调用(隐式绑定)。
- 默认全局对象(在严格模式下未定义)。
网友评论