资讯专栏INFORMATION COLUMN

JavaScirpt 的 bind 函数究竟做了哪些事

mzlogin / 851人阅读

摘要:而且当时,会把的赋给函数,而函数返回的是,所以这时的也赋给了。实例化总结所以函数总共做了哪几件事呢没有实例化时,将传入对象的参数引用到当前函数,执行当前函数,返回结果实例化时,使用操作生成新函数,原函数的赋给新函数,执行新函数,并返回新函数

文章原地址:https://github.com/catchonme/...

ES5 实现 bind 函数如下

Function.prototype.bind = function(that){
        var self = this,
            args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
            F = function(){};

        var bound = function(){
            var context = that, length = arguments.length;
            if (this instanceof bound){
                F.prototype = self.prototype;
                context = new F;
            }
            var result = (!args && !length)
                ? self.call(context)
                : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
            return context == that ? result : context;
        };
        return bound;
    }

测试1

var bar = function() {
        console.log(this.x)
    }
var foo = {
  x: 3
}

var func = bar.bind(foo);
func(); // 3

bar 函数绑定foo 中的x 值,然后输出3

bind 函数中最主要的是bound 函数,bound 函数做了哪些事呢?

首先context 存储传入的thatcontext 中,判断this instanceof bound ,那什么时候this instanceof bound == true 呢?在测试1中的案例中,this instanceof bound false ,打印此时的this 输出Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} ,发现是window 对象,因为foo 本身就是在window 对象中。

所以此时直接执行self.call(context) ,返回执行的结果3 ,就是我们测试1中的结果。

那什么时候this instanceof bound == true 呢,而且此时还需要使用空函数F 来获取主函数的prototype

答案是实例化,什么时候实例化呢?

测试2

var bar = function() {
    console.log(this.x)
}
bar.prototype.name = function(){
  this.name = "name";
}
var foo = {
  x: 3
}

var func = bar.bind(foo);
var newFunc = new func; // undefined
newFunc.name(); // name

bar.bind(foo) 进行实例化,此时因为进行了new 操作,new 操作做了什么呢,参考new操作符里面到底发生了什么?所以此时的this 为新生成的bound {} 对象,constructorbound 函数,所以此时this instanceof bound == true

那为什么bar.bind(foo)foo 对象传递的时候,没有输出3 而是undefined 呢?也是因为new 操作,当前的上下文已经是新生成的newFunc 函数了。而且当this instanceof bound == true 时,会把barprototype 赋给F 函数,而bound 函数返回的是new F ,所以这时barprototype 也赋给newFunc 了。

我们看看ES6的操作,结果和上述例子是一样的。

var bar = function() {
    console.log(this.x)
}
bar.prototype.name = function(){
    console.log("name")
}
var foo = {
    x: 3
}
var func = bar.bind(foo);
func(); // 3
// 实例化
var newFunc = new func; // undefined
    newFunc.name(); // name

总结:

所以bind 函数总共做了哪几件事呢?

没有实例化时,将传入对象的参数引用到当前函数,执行当前函数,返回结果

实例化时,使用new 操作生成新函数,原函数的prototype 赋给新函数,执行新函数,并返回新函数

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94678.html

相关文章

  • 前端基本功-示例代码 (二)

    摘要:前端基本功示例代码一点这里前端基本功示例代码二点这里一像素伪类实现对于老项目,有没有什么办法能兼容的尴尬问题了,个人认为伪类是比较完美的方法了。 前端基本功-示例代码 (一) 点这里前端基本功-示例代码 (二) 点这里 1.一像素 伪类 + transform 实现对于老项目,有没有什么办法能兼容1px的尴尬问题了,个人认为伪类+transform是比较完美的方法了。 原理是把原先元素...

    Java3y 评论0 收藏0
  • 前端基本功-示例代码 (二)

    摘要:前端基本功示例代码一点这里前端基本功示例代码二点这里一像素伪类实现对于老项目,有没有什么办法能兼容的尴尬问题了,个人认为伪类是比较完美的方法了。 前端基本功-示例代码 (一) 点这里前端基本功-示例代码 (二) 点这里 1.一像素 伪类 + transform 实现对于老项目,有没有什么办法能兼容1px的尴尬问题了,个人认为伪类+transform是比较完美的方法了。 原理是把原先元素...

    wpw 评论0 收藏0
  • 深入理解JavaScirpt函数调用和"this"

    摘要:简单的函数调用显而易见,一直用调用函数将会非常烦人。规范说几乎总是被传递,但不在严格模式下时被调用函数应该将其更改为全局对象。实际上,规范有一个和都使用的原语内部称为。 过去很多年里,我看到过太多关于JavaScript函数调用的混淆。尤其是,很多人抱怨函数调用中this的语义令人困惑。在我看来,通过理解核心函数调用原语,然后将其他所有调用函数的方法视为在原语之上的语法糖,如此便可澄清...

    bladefury 评论0 收藏0
  • 2018 浅谈前端面试那些

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    LiuRhoRamen 评论0 收藏0
  • 2018 浅谈前端面试那些

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    stormgens 评论0 收藏0

发表评论

0条评论

mzlogin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<