apply,call学习
一、this
例子1
var name = "windowName"
function getName() {var name = "jack"console.log(this.name) // windowNameconsole.log("inner", this) // window
}getName()
console.log("outer", this) // window
this.name是windowName,因为调用的对象是window,getName() 相当于 window.getName()。如果使用严格模式的话,全局对象就是 undefined
例子2
let name = "windowName"
let user = {name: 'jack',getName: function () {console.log(this.name) // this 指向jack}
}
user.getName()
getName这个函数对象user调用的,应证了那句话“this 永远指向最后调用它的那个对象”
例子3
var name = "windowName"
var user = {name: null,getName: function () {console.log(this.name) // windowName}
}
var fn = user.getName
fn()
因为把函数赋值给了fn,getName并没有调用,最后还是相当于window调用了这对方法,所以结果是 windowName (不要在严格模式下)
this 的指向并不是在创建的时候就可以确定的,在 es5 中,永远是this 永远指向最后调用它的那个对象。
二、改变this的指向
- 备份指针
- 箭头函数
- apply、call、bind
例子4
name = "windowName"
var user = {name: null,getName: function () {console.log(this.name)},test: function () {setTimeout(function () {this.getName() // 报错 TypeError: this.getName is not a functionvar}, 100)}
}
user.test()
在不使用箭头函数的情况下,是会报错的,因为最后调用 setTimeout 的对象是 window,但是在 window 中并没有 func1 函数。
(1)箭头函数
箭头函数的 this 始终指向函数定义时的 this,而非执行时。
var name = "windowName"
var user = {name: "jack",getName: function () {console.log(this.name) // this 指向jack},test: function () {setTimeout(() => {this.getName()}, 100)}
}
user.test()
箭头函数修正了this的指向
(2)备份指针
var name = "windowName"
var user = {name: "jack",getName: function () {console.log(this.name) // tack},test: function () {var self = this // 备份指针setTimeout(function () {self.getName()}, 100)}
}
user.test()
(3)apply、call、bind
使用 apply、call、bind 函数也是可以改变 this 的指向的
使用apply
var user = {name: "jack",getName: function () {console.log(this.name) // jack},test: function () {setTimeout(function () {this.getName()}.apply(user), 100)}
}
user.test()
使用call
var user = {name: "jack",getName: function () {console.log(this.name) // jack},test: function () {setTimeout(function () {this.getName()}.call(user), 100)}
}
user.test()
使用bind
var user = {name: "jack",getName: function () {console.log(this.name) // jack},test: function () {setTimeout(function () {this.getName()}.bind(user)(), 100)}
}
user.test()
(4)apply、call、bind 区别
apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数
语法
func.apply(thisArg, [argsArray])
- thisArg
可选的。在func函数运行时使用的this值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null或undefined时会自动替换为指向全局对象,原始值会被包装。 - argsArray 可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给
func函数。如果该参数的值为null或undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 浏览器兼容性 请参阅本文底部内容。 - 返回值 调用有指定
this值和参数的函数的结果。
(5)call 和 apply的区别
apply 和 call 基本类似,他们的区别只是传入的参数不同。
fun.call(thisArg[, arg1[, arg2[, ...]]])
call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。
例子 (apply)
var operation = {sum: function (a, b) {console.log(a + b) // 3}
}var a = operation.sum
a.apply(operation, [1, 2])
例子 (call)
var operation = {sum: function (a, b) {console.log(a + b) // 3}
}var a = operation.sum
a.call(operation, 1, 2)
(6)bind 和 apply、call 区别
还是刚刚的例子
var operation = {sum: function (a, b) {console.log(a + b) // 3}
}var a = operation.sum
a.bind(operation, 1, 2)()
(7)创建对象时候使用call
function Person(name, age) {this.name = namethis.age = age
}
var person = new Person('jack', 18)
person.name // jack
简单的来看一下 new 的过程吧:
var person = new Person('jack', 18)new Person {var obj = {}obj.__proto__ = myFunction.prototype;var result = myFunction.call(obj,"jack","18");return typeof result === 'obj'? result : obj;
}
- 创建一个空对象
- 将新创建的空对象的隐式原型指向其构造函数的显示原型
- 使用
call改变this的指向 - 如果无返回值或者返回一个非对象值,则将
obj返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
