this
this是js函数的内部属性,指向当前执行代码的环境对象
一般函数调用模式
function fn(){
console.log(this);
}
fn(); //Window
对象方法调用模式
var obj = {
name: "objname",
getname: function () {
console.log(this.name);
}
}
obj.getname(); //objname
var name = 'winname'
var getname = obj.getname;
getname(); //winname
将对象的方法赋给变量后,就脱离了与obj的关系
回调函数
setTimeout(function() {
console.log(this) //window
function fn(){
console.log(this) //window
}
fn()
}, 0);
回调函数的执行环境是window
经典面试题
function a(xx) {
this.x = xx;
return this
};
var x = a(5);
var y = a(6);
console.log(x.x); //undefined
console.log(y.x); //6
a(5)执行时将window.x赋值为5,但返回值又将window.x覆盖掉变为window
a(6)执行时将window.x赋值为6,要输出x.x也就是6.x,6是数值,并没有赋值x属性,也就undefined了
var a = 10;
var obt = {
a: 20,
fn: function () {
var a = 30;
console.log(this.a)
}
}
obt.fn(); // 20
obt.fn.call(); // 10
(obt.fn)(); // 20
(obt.fn, obt.fn)(); // 10
(obt.fn=obt.fn)(); // 10
new obt.fn(); // undefined
通过以下三种方式可以修改this指向
function person(name) {
this.name = name;
this.who = function () {
console.log(this.name);
}
}
apply()
function man(name, age) {
person.apply(this, [name]);
this.sex = 'man';
this.age = age;
this.info = function () {
console.log(this.name + ':' + this.sex + ',' + this.age);
}
}
var p1 = new man('wang', 28);
p1.info(); //wang:man,28
apply的参数以数组方式传递
call()
function woman(name, age) {
person.call(this, name);
this.sex = 'woman';
this.age = age;
this.info = function () {
console.log(this.name + ':' + this.sex + ',' + this.age);
}
}
var p2 = new woman('li', 18);
p2.info(); //li:woman,18
call的参数以序列化方式传递
bind()
function neutral(age) {
this.sex = 'unknown';
this.age = age;
this.info = function () {
console.log(this.name + ':' + this.sex + ',' + this.age);
}
}
var p3 = new neutral(38);
person.bind(p3)('jing');
p3.info(); //jing:unknown,38
bind不立即执行,而是返回一个函数,需再次手动执行