this浅看
一些浅见。
this对象是在运行时基于函数的执行环境绑定的。
一、非对象函数定义中的this
//非对象定义函数
//当函数被单独定义和调用的时候,应用的规则就是绑定全局变量
const fn1 = () => {
console.log(this)
};
fn1();
var fn2 = function () {
console.log(this)
};
fn2()
无关严格模式还是非严格模式,也无关箭头函数写法还是普通写法,打印的都是 window对象。
二、对象扩展中的this
var obj1 = { write: function () { console.log(this.color); console.log("obj1"); }, color: "red" }; obj1.write(); var obj3 = { write(){ console.log(this.color); console.log("obj3") }, color: "red" }; obj3.write();
ES6 允许直接写入变量和函数,作为对象的属性和方法。也可以简写。obj3中write方法就是简写的。obj1和obj3是一样的。
打印Object对象;
function fn() { console.log(this) } var obj4 = { write: fn };
obj4.write()
fn();
打印Object对象(obj4);
打印window对象;
this调用时的上下文。
function fn() { console.log(this) } var obj4 = { write: fn }; var obj5 = { obj: obj4 }; obj5.obj.write()
打印Object对象(obj4);
this调用时的最初的上下文。
function fn() { console.log(this) } var obj4 = { write: fn }; var _fn = obj4.write;
obj4.write();
_fn();
打印Object对象(obj4);
打印window对象;
牵扯一些引用问题:
function fn() { console.log(this) } var obj4 = { write: fn, }; var _fn = obj4.write; obj4.write(); _fn(); var obj = obj4; obj.color = "blue"; console.log(obj4.color); console.log(obj.color);
打印都是blue。
修改obj.color时obj4.color也一起改变了----obj = obj4不是复制黏贴一个新的对象,而是新创建一个变量并将obj4指向的地址又赋值给了新的变量,属于地址引用(地址在栈中,读取栈内存中该地址,然后在堆中找到相应的内容,多对一的关系)
var obj1 = { write() { setTimeout(function () { console.log(this); console.log("obj1") }); } }; obj1.write(); var obj2 = { write(){ setTimeout(()=> { console.log(this); console.log("obj2"); }, 0); }, color: "red" }; obj2.write();
打印window对象;
打印Object对象(obj2)
var obj5 = {
name:"obj",
getName:function () {
return function () {
console.log(this)
}
}
};
obj5.getName()();
打印window对象。
return返回的匿名函数this访问到window即停止了,而且return返回的闭包并不能访问到外部变量。
三、遇见call\apply\bind
function fn() { console.log(this.color) } var obj4 = { color:"red" }; fn.call(obj4)
打印red;
将fn中this指向obj4
四、new出来一个新对象(引Javascript高级程序设计 第3版)
// 构造函数模式创建对象
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name)
}
}
var person1 = new Person("Ni",29,"SE");
var person2 = new Person("Gr",27,"Doctor");
要创建Person的新实例,必须使用new操作符。以这种方式调用构造函数。。。会经历以下四个步骤:
(1).创建一个新的对象;(一个空对象{})
(2).将构造函数的作用域赋给新对象(obj.__proto__ = Person.prototype);
(3).执行构造函数中的代码Person.call(obj)(为这个新对象添加属性,改变this指向);
(4).返回新对象。(赋新对象地址)