this定义
this就是指针, 指向我们调用函数的对象; this是JavaScript中的一个关键字,它是函数运行时,在函数体内自动生成的一个对象,只能在函数体内部使用。
this规则
this 是很多人会混淆的概念,但是其实他一点都不难,你只需要记住几个规则就可以了。
- 全局环境中this指向全局变量(window)
- this一旦绑定,就不会被任何代码更改。
- 对this来说,
new
的优先级是最高的,如果let c=new foo()
,那么foo()
里的this就都会绑定在c上。 - call、apply、bind改变this,优先级仅次于new。
- 箭头函数的this取决于它外面第一个不是箭头函数的函数的this。
- 函数中的this,由调用函数的方式来决定(1)如果函数是独立调用的,在严格模式下(use strict)是指向undefined的,在非严格模式下,指向window(2)如果这个函数是被某一个对象调用,那么this指向被调用的对象;
this经典题
/*-----------题目一-------------------*/
var obj = {
a: 10,
b: this.a + 10, //这里的this指向window(规则1),a为undefined
fn: function () {
return this.a;
}
}
console.log(obj.b); //NaN(规则1)
console.log(
obj.fn(), //10(规则6(2))
obj.fn
//fn (干扰项,未加()的函数相当于一个变量,函数只有加()才会运行,返回对应的返回值)
);
复制代码
/**-------------题目二 ----------------*/
var a = 20;
var obj = {
a: 10,
getA: function () {
return this.a;
}
}
console.log(obj.getA()); //10
var test = obj.getA; // test的值为:function (){ return this.a;}
console.log(test()); // 20
// 调用test(),相当于调用function (){ return this.a;},
// 相当于独立调用function (){ return this.a;}(规则6(1))
复制代码
/*-----------题目三-------------------*/
var a = 5;
function fn1(){
var a = 6;
console.log(a); //6
console.log(this.a); //5
}
function fn2(fn) {
var a = 7;
fn();
}
var obj = {
a: 8,
getA: fn1 // 注意,fn1不加()相当于变量赋值
// 相当于:getA: function() {var a = 6; console.log(a); //6 console.log(this.a); //5}
}
fn2(obj.getA); // 6 5 //注意,此时obj.getA也没加(),也相当于变量赋值,
//相当于: fn2(function() {var a = 6; console.log(a); //6 console.log(this.a); //5}
// 所以函数还是相当于独立调用,输出6 5。 (规则6(1))
复制代码
/*-----------题目四-------------------*/
function fn( ) {
'use strict';
var a = 1;
var obj = {
a: 10,
c: this.a + 20 //严格模式下,a指向undefined嘛,undefined.a报错
}
return obj.c;
}
console.log(fn()); //输出报错==》 a undefined(规则6(1))
复制代码
/*-----------题目五-------------------*/
// 声明一个构造函数
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this);
}
// Person(); //this 指向window
Person.prototype.getName = function () {
console.log(this);
};
var p1 = new Person("test", 18);// Person {name: "test", age: 18}
p1.getName();// Person {name: "test", age: 18}
复制代码
var obj = {
foo: "test",
fn: function(){
var mine = this;
console.log(this.foo); //test
console.log(mine.foo); //test
(function(){
console.log(this.foo); //undefined 由于这个立即函数是独立调用的,所以this指向window(规则6(1))
console.log(mine.foo); //test
})();
}
};
obj.fn();
复制代码
/* --------- 题目七 ----------- */
function foo(){
console.log(this.a);
}
var a = 2;
var o = {
a:3,
foo: foo
};
var p = { a:4 };
o.foo(); //3
(p.foo = o.foo)(); //2 注意没加()就是变量赋值,立即执行函数独立调用,所以this指向window(规则6(1))
p.foo = o.foo;
p.foo(); //4 函数由p执行,p调用指向p(规则6(2))
复制代码
/* --------- 题目八 ----------- */
function foo() {
console.log(this.a);
}
var obj1 = {
a: 3,
foo: foo
};
var obj2 = {
a: 5,
foo: foo
};
obj1.foo(); //3(规则6(2)
obj2.foo(); //5(规则6(2)
obj1.foo.call(obj2); //5(规则4)
obj2.foo.call(obj1); //3(规则4)
复制代码
/* --------- 题目九 有意思的一题----------- */
function test(arg) {
this.x = arg;
return this;
}
/**
var x = test(5); --> window.x = window.test(5);
*/
var x = test(5); //此时x = window 后面的x(window)覆盖了前面的x(5)
var y = test(6); //此时 x = 6, y = window , 后面的x(6)覆盖了前面的x(window)
console.log(x.x); //undefined, 实际上是6.x 是undefined(规则6(2))
console.log(y.x); //6 实际上是window.x 也就是6 (规则6(2))
复制代码
/* --------- 题目十 ----------- */
var obj = {
data: [1,2,3,4,5],
data2: [1,2,3,4,5],
fn: function () {
console.log("--test--");
console.log(this); //{data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ}
return this.data.map(function (item) {
console.log(this); // --> window (独立调用(规则6(1)))
return item * 2;
});
},
fn2: function () {
console.log("---test2---");
console.log(this); //{data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ}
return this.data2.map(item=>{
console.log(this); // --> obj {data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ} 箭头函数(规则5)
return item * 2;
});
}
};
obj.fn();
obj.fn2();
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END