博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
刷题-5
阅读量:6715 次
发布时间:2019-06-25

本文共 2317 字,大约阅读时间需要 7 分钟。

刷题-5 bind 相关问题

题目1

function f() {  console.log(this);}let f1 = f.bind(1).bind(2)f1()复制代码

解析:

  • bind 基本实现(不完整)
Function.prototype.bind = function (thisArg) {    var _this = this    return function () {        _this.apply(thisArg)    }}复制代码
  • bind 原理:

    bind的原理, bind的作用是永久改变一个函数执行过程中的this,它的基本实现 bind的执行不会立即执行需要改变this指向的函数  bind执行后返回一个新函数  新函数调用会间接调用源函数来实现源函数的执行  函数执行过程中通过apply(apply、call)把this指向thisArg 闭包:  内层函数可以访问外层数据 内层:return 后面的函数    外层:bind函数阻止垃圾回收,  所以即使bind已经执行完成了,但是因为return的函数被外部引用,  所以bind中的thisArg并没有被回收,  这样后续无论什么时候调用return出去的函数都能访问到thisArg复制代码
  • 所以:

function f() {      console.log(this);    }    let f1 = f.bind(1).bind(2);    f1();        // 其实可以看成下面的调用        let temp = f.bind(1);    let f1 = temp.bind(2);    f1();        首先 temp 是 f.bind(1) 的结果    temp = function(1) {        // 这里的 thisArg = 1        function() {            f.apply(1);        }    }        //也就是temp调用的时候接收了一个1的参数,然后间接的调用了f,并把f的this指向了temp的参数1    //然后 let f1 = temp.bind(2) 执行以后 f1 代码    f1 = function(2) {    // 这里的 thisArg = 2    function() {        temp.apply(2);        }    }    // f1调用的时候接收了一个2的参数,然后间接的调用了temp,并把temp的this指向了2复制代码
  • 重点:

其实这里特别注意的是其实f1调用了temp并确实改了temp的this为2,但是这里是没有调用最开始的f的,而是temp.apply(2)的时候再去调用的f.apply(2),所以无论中间有多少层bind,最后那个f调用永远都是最开始的1

let temp = f.bind(1);let f1 = temp.bind(2);let f2 = f1.bind(3);let f3 = f2.bind(4);let f4 = f3.bind(5);f4();f4() => f3.apply(5) => f2.apply(4) => f1.apply(3) => temp.apply(2)=>f.apply(1)复制代码

就是bind一次包一层函数,每一次都有自己的this指向,最后一次执行的也就是最开始bind的才会执行初始绑定的函数,改变它的this.

题目 2

function f() { console.log(typeof this);}let f1 = f.bind(1).bind(2)let val = f1() // object复制代码
  • 重点:

this 永远必须是个 对象,不能是其他类型,虽然不能直接赋值,但是可以通过callapplybind 内部改变 this,但是为了确保 this 为对象类型,如果赋给他的值是非对象的,则会转成对象

  • 解析:

    • Number、String、Boolean 是 javascript 内置的三个基本类型包装对象
    • null 和 undefined 没有对象包装对象(类) this 指向将不会改变,等同于 f() 直接调用
function f() {  console.log(typeof this, this);}f.call(0)// object Number {0}   其实是: new Number(0)f.call('hello world')  // object String {"hello world"} 其实是: new String('hello world')f.call(true)// object String {"hello world"} 其实是: new Boolean(true)f.call(null)// object Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}f.call(undefined)// object Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}复制代码

转载于:https://juejin.im/post/5d01f0055188257f6d3c66fe

你可能感兴趣的文章
iOS 网易新闻用到的框架
查看>>
301重定向方法大全及SEO中网址规范化,看着不错先收下
查看>>
Windows Live Writer 在线安装失败的解决方法。
查看>>
基于Geoserver发布时间地图
查看>>
使用DOSBox在Win7_x64下搭建汇编环境
查看>>
js插件大全 jquery插件大全
查看>>
解决ubuntu 14.04删ibus导致系统设置项目的损失后,,退出关机问题是不正常的
查看>>
理解vmp
查看>>
CentOS6.4下Mysql数据库的安装与配置
查看>>
[转]GC简介
查看>>
poj 1466 Girls and Boys (最大独立集)
查看>>
辛星与您使用CSS导航条
查看>>
统计一个文件中出现字符'a'的次数
查看>>
将Eclipse包括第一3正方形jar包裹Project Export并产生能够执行jar
查看>>
Google Pagespeed,自动压缩优化JS/CSS/Image
查看>>
Gentoo源码安装图解
查看>>
【转载】COM 组件设计与应用(三)——数据类型
查看>>
Python yield与实现
查看>>
购物车特效收集
查看>>
Access中一句查询代码实现Excel数据导入导出
查看>>