全局环境下this就是 window 对象的引用
window.name='xxx'
function global(){
console.log(this);//window
console.log(this.name);//xxx ---window.name
}
global()
但是在严格模式下,全局函数内this为undefined
方法调用
普通函数中的this指向
- 当函数为对象里的方法时this 指向该对象,也就是该函数为对象里的一个属性例如下面的 fangfa()
- 当函数为对象里方法里面的一个方法时,他就是一个普通的全局函数,他的this指向window,例如 fangfa()里面的son()函数
箭头函数中的this指向
- 当 函数为箭头函数的时候,他的指针和他的父级函数的指针相同,指向同一个对象,如果他没有父级函数,就是指向window,
- 例如getThis(),如果他有父级函数,就和父级函数的this一样,
- 例如but[0].addEventListener(),他里面的函数是指针函数,所以他的指向就是根据上下文,也就是和他的父级函数fangfa()指向一样,都是指向data这个对象
- 相比之下but[1].addEventListener(),里面是function(){},他就相当于是but[1]里面的一个方法,所以他指向but[1],它里面的function but1_son()就指向 window,()=>里的this指向but[1]
data={
site:'xxx',
getThis:()=>{
console.log(this);//window,箭头函数的this的指向和他父级函数的指向相同
},
fangfa:function(){
console.log(this);// {site: 'xxx', getThis: ƒ, fangfa: ƒ}
// 这个this指向的就是这个对象
function son()
{
console.log(`fangfa-son+${this}`);//window 对象里第一层的函数被称为方法,this指向对象,第二层(函数里面的函数)就是普通的全局函数,this指向window
}
son()
but[0].addEventListener('click',(e)=>{
console.log(e.target);
console.log(this);//这里是箭头函数,他的父级是fangfa,fangfa的this指向的是data,所以这个this也是指向data
// })
but[1].addEventListener('click',function(){
//这个function是but对象里的方法,所以this指向but[1]
console.log(this);//<button>点击按钮2--function</button>,
(function but1_son(){
console.log(this);//window 这个funtion就是一个全局函数了
})();
(()=>{
console.log(this);//这个就和他的父级-function指向相同了,<button>点击按钮2--function</button>
})()
})
}
}
构造函数
构造函数可以用来创建对象
function User() {
this.name = "xxx";
this.say = function() {
console.log(this); //User {name: "xz", say: ƒ}
return this.name;
};
}
let hd = new User();
console.log(hd.name);//xxx
console.log(hd.say()); //xxx
改变函数中的this指向的方式
①把要用的this赋值给一个变量或常量
let Lesson = {
site: "课程",
lists: ["js", "css", "mysql"],
show() {
return this.lists.map(function(title) {
//这里的this原本是应该指向window的,但是因为map()里面的第二个参数可以设置this,此处就是把show()里面的this赋值了进来
console.log(this); //{site: '课程', lists: Array(3), show: ƒ}
return `${this.site}-${title}`;
}, this);
}
};
console.log(Lesson.show());// ['课程-js', '课程-css', '课程-mysql']
②使用 apply,call,bind等方法
这三个方法都是用来改变函数里面的this指向的
1.call() /apply()
call 与 apply 都是用于将对象绑定到 this,只是在传递参数上有所不同。apply 用数组传参,call 需要分别传参,这两个方法都会立即执行
function User(name,age) {
this.name = name;
this.age=age
}
let xxx={};
//第一个参数是要设置的指针指向,这里是让User的this指向xxx
//第二个参数是 User()中要传入的参数
User.call(xxx,'xiaozhuo',22)
//User.apply(xxx,['xiaozhuo',22])
console.log(xxx);//{name: 'xiaozhuo', age: 22}
案例:实现构造函数属性继承
function Request() {
this.get = function(params = {}) {
//组合请求参数
let option = Object.keys(params)
.map(i => i + "=" + params[i])
.join("&");
return `获取数据 API:${this.url}?${option}`;
};
}
function Lesson() {
this.url = "lesson/index";
Request.call(this);
}
let js = new Lesson();
console.log(
js.get({
row: 20
})
)//获取数据 API:lesson/index?row=20
2.bind()
bind()是将函数绑定到某个对象,比如 a.bind(hd) 可以理解为将 a 函数绑定到 hd 对象上即 hd.a()。
- 与 call/apply 不同 bind 不会立即执行
- bind 是复制函数形为会返回新函数
bind 是复制函数行为
function hd(a, b) {
return this.f + a + b;
}
let a={f:1}
//使用bind会生成新函数
let newFunc = hd.bind(a);//这里newFunc 的指向就指向a了
console.log(newFunc(2,3));//6
let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc());//10
let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc(2,5));//10 还是会采用之前传入的参数
let newFunc = hd.bind(a,3);//这里newFunc 的指向就指向a了
console.log(newFunc(5));//9
要注意bind()里面的参数传入
function hd(a, b) {
return this.f + a + b;
}
let a={f:1}
let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc(2,5));//10 还是会采用之前传入的参数