一、call()
、apply()
相同点:call()
和apply()
的第一个参数都是this
;如果不给this
传值,那么this
就是undefined,宽松模式下,undefined
就是Window
;严格模式下,undefined就是undefined;
不同点:call()
从第二个参数开始,可以接收任意个参数,每个参数都会映射到相应位置的Function的参数位置上;而apply()
的第二个参数必须是数组,然后把它传入Fuction中,映射到相应的参数位置;
用处:
- 改变函数作用域
var name = '小白'
var obj = {name:'小红'}
function sayName() {
return this.name
}
console.log(sayName.call(this)) //小白
console.log(sayName. call(obj)); // 小红
- 实现js继承
//创建父构造函数
function Person(name,age){
this.name = name
this.age = age
this.showName = function(){
console.log(this.name)
}
}
// 设置父构造函数的原型对象
Person.prototype.showAge = function(){
console.log(this.age)
}
// 创建子构造函数
function Student(name,score){
Person.call(this,name) // !!!!!使用call借用Person的构造函数
this.score = score
}
Student.prototype.score = function(){
console.log(this.score)
}
var f = new Student('hh',100)
// 设置继承
f.__proto__.__proto__ = Person.prototype
二、bind()
-
bind()
和call()
、apply()
的作用相似,区别在于使用上,bind()返回的是一个绑定了新对象的函数,看下例:
-
var obj = {name: '逗逗'}
function sayName(){
console.log(this.name)
}
var fn = sayName.bind(obj) // 注意 这里 fn 还是一个函数,功能和 sayName 一模一样,区别只在于它里面的 this 是 obj
fn() // 逗逗
再看一个例子:
var app = {
container: document.querySelector('body'),
bind: function(){
this.container.addEventListener('click', this.sayHello)
this.container.addEventListener('click', this.sayHello.bind(this))
},
sayHello: function(){
console.log(this)
}
}
app.bind()
来一一解析,
this.container.addEventListener('click', this.sayHello)
,此处这边两个this
都是指的app对象,当点击body
的时候执行sayHello,这时sayHello函数绑定的对象是this.container
,也就是body
,所以这时点击body
,sayHello 函数里面的 this 代表 body 对象;
this.container.addEventListener('click', this.sayHello.bind(this))
与上面那个不同的是,this.sayHello.bind(this)
返回的是一个功能与sayHello一模一样,绑定对象为app对象的函数,所以点击body的时候会执行 sayHello,sayHello 里面的 this 代表 app 对象;
- 箭头函数的this指向
let app = {
fn1: function(a){
console.log(this) //app
}
fn2(a) {
consoel.log(this) //app
},
fn3: (a)=>{
console.log(this) //window
}
}
网友评论