js中的call

JavaScript024

js中的call,第1张

java中对象包含属性和方法, 方法即函数, 只有对象可以调用方法

但是js中一切皆对象, 函数是对象, 函数也可以调用方法

Function.prototype.call

Function.prototype.apply

Function.prototype.bind

Function.prototype.toString

为什么js语言会在function原型上挂上这四个函数?

因为好处太多了, 现在我就说一说call的应用

再深入思考一下, call语法是基于什么形成的呢 ?

了解底层语法有助于我们理解高级的语法

因为在底层的语法眼中, 高级语法只不过是工具, 根本不算语法, 不过是由我定义构建处理来的

理解call函数, 核心必要知识

哈哈哈, v8内部的不知道, 反正js基于现有语法就有这个能力 (还有解法, 基于 proto ,原型链的方式, var temp = Object.create(null)), 利用干净的地方, 防止覆盖原对象的函数

显然, 我们自己的上面的mycall还要很多问题

这里我们就实现了自己的call, 以后看见call就知道都不过是些雕虫小技了(当然真实的实现方式肯定需要考虑更多因素和性能, 而且在v8更大的环境下, 可能还不止一种实现方式,保持谦虚)

1.apply与call是更改对象的内部指针,即改变对象的this指向的内容;

2.call与apply的第一个参数都是要传入给当前对象的对象,及函数内部的this,后面的参数都是传递给当前对象的参数。

详细用法如下:

1.call()

语法:obj1.call(obj2[,param1,param2,...]);

定义:用obj2对象来代替obj1,调用obj1的方法。即将obj1应用到obj2上;

说明:call 方法可以用来代替另一个对象调用一个方法,call 方法可将一个函数的对象上下文从初始的上下文改变为由 obj2 指定的新对象,如果没有提供 obj2参数,那么 Global 对象被用作 obj2。

2.apply()

语法:obj1.call(obj2[,arrArg]);

定义:用obj2对象来代替obj1,调用obj1的方法,即将obj1应用到obj2上,

说明:call ()和apply()作用一样,但是call()可以接收任何类型的参数,而apply()只能接收数组参数。

3.基本用法

4.继承特性

call和apply

obj.call(thisObj, arg1, arg2, ...)

obj.apply(thisObj, [arg1, arg2, ...])

两者作用一致,都是把obj(即this)绑定到thisObj,这时候thisObj具备了obj的属性和方法。或者说thisObj『继承』了obj的属性和方法。绑定后会立即执行函数。

唯一区别是apply接受的是数组参数,call接受的是连续参数。

function add(j, k){

return j+k

}

function sub(j, k){

return j-k

}

我们在控制台运行:

add(5,3)//8

add.call(sub, 5, 3)//8

add.apply(sub, [5, 3])//8

sub(5, 3)//2

sub.call(add, 5, 3)//2

sub.apply(add, [5, 3])//2

调用原生对象的方法

示例:

var a = {0:1, 1:"yjc", length: 2}

a.slice()//TypeError: a.slice is not a function

Array.prototype.slice.call(a)//[1, "yjc"]

对象a类似array,但不具备array的slice等方法。使用call绑定,这时候就可以调用slice方法。

实现继承

通过call和apply,我们可以实现对象继承。示例:

var Parent = function(){

this.name = "yjc"

this.age = 22

}

var child = {}

console.log(child)//Object {} ,空对象

Parent.call(child)

console.log(child)//Object {name: "yjc", age: 22}

以上实现了对象的继承。

bind的使用

obj.bind(thisObj, arg1, arg2, ...)

把obj绑定到thisObj,这时候thisObj具备了obj的属性和方法。与call和apply不同的是,bind绑定后不会立即执行。

同样是add()和sub():

add.bind(sub, 5, 3)//不再返回8

add.bind(sub, 5, 3)()//8

如果bind的第一个参数是null或者undefined,等于将this绑定到全局对象。