这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将bind方法用ES3重写,使用bind这个方法,导致一时半会懵了,只记得bind可以改变this的作用域。

作为查漏补缺,这里来研究并做笔记。

this:

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象。
  • 在函数中,this 表示全局对象。
  • 在函数中,在严格模式下,this 是未定义的(undefined)。
  • 在事件中,this 表示接收事件的元素。
  • 类似 call() 和 apply() 方法可以将 this 引用到任何对象。

这东西有点绕,所以用实际例子来测试一下。

由于javaSrcipt在函数中的this指向的是全局作用域,所以下面返回undefined

 1 var log = {
2 sayname () {
3 var func = function () {
4 console.log(this.name)
5 }
6 func();
7 }
8 name: 'li'
9 }
10
11 log.sayName() // undefined

修改一下:

使用that临时储存this的作用域,此时指向对象本身

 1 var log = {
2 sayname : function () {
3 // 由于是在对象中,this指向该对象本身,即log
4 var that = this
5 var func = function () {
6 console.log(that.name)
7 }
8 func();
9 }
10 name: 'li'
11 }
12
13 log.sayname() // li

当前其他情况大部分都是指向全局this,浏览器是window,node是Golbal

1 console.log(this) // window

关于this暂时到这。

bind()

用法:

Function.bind(this [,arg1,arg2,...])

第一个参数是绑定的作用域

第二个及以后的参数则作为函数的参数调用

call()、apply()、bind() 都是用来重定义 this 这个对象的!其他两个再研究

上面那段代码,可以用bind解决作用域的问题

 1  var log = {
2 sayname : function () {
3 var func = function () {
4 console.log(this.name)
5 }.bind(this)
6 func();
7 }
8 name: 'li'
9 }
10
11 log.sayname() // li

bind还有一种用法,即传参的情况

如:

 1 var name = '小明'
2 var log = {
3 name: '小红',
4 sayname : function (age, loc) {
5 var func = function () {
6 console.log(this.name + "年龄:" + age + "住在:" + loc)
7 }
8 func();
9 }
10 }
11
12 var db = {
13 name: '汤姆'
14 }
15
16 log.sayname.bind(db, 20, '广州')() // 汤姆年龄:20 住在:广州
17 log.sayname.bind(db, 20, [‘广州’, '深圳'])() // 汤姆年龄:20 住在:广州,深圳
18 // bind会将数组当做一个参数传输,而apply则会将数组拆分为参数。

bind()的一个参数,是绑定的对象,this将指向该对象,后面则为方法中需要的参数。

bind()的返回值是一个函数。即可能是下面这种情况。

log1 = log.sayname.bind(db, 20);
log1('广州');
// 结果上同 // 汤姆年龄:20 住在:广州

关于apply,用久了ES6的扩展运算符,容易忘了这个东西(哭,我的错)

好了,下面是重点,上面只是bind的用法,这个遇到的是,Polyfill这个方法。一时懵了。

先分析一下Polyfill这个问题

一、能够改变this的指针

二、能够传参

先解决第一个问题:

 1 Function.prototype.bind = function (context) {
2 // this此时为调用该bind的对象
3 var self = this;
4 // 由于bind返回方法,这里直接返回方法
5 return function () {
6 // 改变this指针,将上下文传入
7 return self.apply(context)
8 }
9 }
10
11 function test() {
12 return this.name;
13 }
14
15 var testname = {
16 name: 'lihua'
17 }
18
19 test.bind(testname)(); // lihua

1.1述代码仍然有问题,只能绑定作用域,返回后的函数,无法传入参数

即: test.bind(testname) (1,2,3,4,5)  传入多少个参数都是获取不到的

 1  Function.prototype.bind = function (context) {
2 // this此时为调用该bind的对象
3 var self = this;
4 // 由于bind返回方法,这里直接返回方法
5 return function () {
6 // 改变this指针,将上下文传入
7 return self.apply(context, arguments) // 增加了arguments,apply会将其作为参数传入
8 }
9 }
10
11 function test(age, loc) {
12 return this.name + ‘’ + 'age' + age + 'loc' + loc;
13 }
14
15 var testname = {
16 name: 'lihua'
17 }
18
19 test.bind(testname)(20, '深圳'); // lihua age:20 loc: 深圳

这样还有问题,即绑定的时候是可以传入默认值的,上述context传入的只是testname这个对象,所以bind(testname, 20)('深圳') 是无法获取到20这个值的

再改:

 1 Function.prototype.bind = function (context) {
2 // 将类数组转为真数组
3 var arg = Array.prototype.slice.call(argument, 1)
4 // arg [20]
5 var self = this;
6 return function () {
7 // 由于apply的第二个参数只能是一个数组,所以需要将两个数组进行合并
8 var insideArgs = Array.prototype.slice.call(arguments);
9 // insideArgs ['深圳']
10 var fullArgs = arg.concat(insideArgs);
11 return self.apply(context, fullArgs)
12 }
13 }
14
15 function test(age, loc) {
16 return this.name + '' + 'age: ' + age + 'location:' + loc;
17 }
18
19 var testname = { name: 'Liang'}
20
21 test.bind(testname, 20)(深圳);

知耻而后勇,每次发现都能够知道自己的不足之处,才能对自己有提升。

开心的是自己又知道了自己的不足之处,不开心的事,笔试在我看来不理想(哭)

Javascript中this作用域以及bind方法的重写的更多相关文章

  1. 浅析 JavaScript 中的 Function.prototype.bind() 方法

    Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数 ...

  2. JavaScript 中的 Function.prototype.bind() 方法

    转载自:https://www.cnblogs.com/zztt/p/4122352.html Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个 ...

  3. javascript中的call(),apply(),bind()方法的区别

    之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再 ...

  4. 认识javascript中的作用域和上下文

    javascript中的作用域(scope)和上下文(context)是这门语言的独到之处,这部分归功于他们带来的灵活性.每个函数有不同的变量上下文和作用域.这些概念是javascript中一些强大的 ...

  5. 深入理解JavaScript中的作用域和上下文

    介绍 JavaScript中有一个被称为作用域(Scope)的特性.虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域.理解作用域将使你的代码脱颖而出,减 ...

  6. JavaScript中的作用域

    很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...

  7. 【翻译】JavaScript中的作用域和声明提前

    原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译开始=== 你知道下面的JavaScript脚本执 ...

  8. JavaScript中的作用域和声明提前

    [翻译]JavaScript中的作用域和声明提前 原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译 ...

  9. 深入了解JavaScript中的Symbol的使用方法

    这篇文章主要介绍了深入了解JavaScript中的Symbol的使用方法,本文针对ES6版本的JS进行讲解,需要的朋友可以参考下 Symbol 是什么? Symbols 不是图标,也不是指在代码中可以 ...

随机推荐

  1. php第三天-数组的定义,数组的遍历,常规数组的操作

    0x01 数组分类 在php中有两种数组:索引数组和关联数组 索引数组的索引值是整数,以0开始.当通过位置来标识东西时用索引数组. 关联数组是以字符串作为索引值,关联数组更像操作表.索引值为列名,用于 ...

  2. 【JAVA】HashMap源码阅读

    目录 1.关键的几个static参数 2.内部类定义Node节点 3.成员变量 4.静态方法 5.HashMap的四个构造方法 6.put方法 7.扩容resize方法 8.get方法 9.remov ...

  3. C#实现创建、编辑NX表达式

    在NX8.5中使用C#编辑表达式中有个坑,part.Expressions.Edit该方法鲁棒性很差,当表达式有错时也能编辑成功(手动在NX中增加错误表达式会有弹框,无法创建,而该方法却可以,疑是bu ...

  4. vue学习03 v-html

    vue学习03v-html v-html指令的作用是:设置元素的内部html链接 内容有html 的结构会被解析为标签 v-text指令无论内容是什么,只会解析文本 解析文本使用v-text,需要解析 ...

  5. 升​级​到​w​i​n​8​.​1​导​致​o​r​a​c​l​e​服​务​丢​失​的​处​理

    针对升级到win8.1导致oracle服务丢失的处理 1.首先保证oracle相关程序能够运行,如net manager,如果能够运行,说明oracle安装仍然有效,只是因为服务被"净化&q ...

  6. OpenCV图像处理学习笔记-Day03

    OpenCV图像处理学习笔记-Day03 目录 OpenCV图像处理学习笔记-Day03 第31课:Canny边缘检测原理 第32课:Canny函数及使用 第33课:图像金字塔-理论基础 第34课:p ...

  7. P4231 三步必杀

    题目描述 问题摘要: N个柱子排成一排,一开始每个柱子损伤度为0. 接下来勇仪会进行M次攻击,每次攻击可以用4个参数l,r,s,e来描述: 表示这次攻击作用范围为第l个到第r个之间所有的柱子(包含l, ...

  8. 《To C产品经理进阶》

    我所说的,都是错的. To C产品设计和To B产品设计对一个优秀的产品经理的洞察能力.架构能力有共通的要求. 实际产品设计过程中,To C产品往往是从商业思维思考,侧重用户研究,思考用户心智,由产品 ...

  9. IDEA2020.2的破解

    第一种方式:http://code.39sd.cn/ 直接获取二维码: 第二种:下载破解工具(本方法只是提供个人学习使用) 1.下载2020.2的idea 链接:https://pan.baidu.c ...

  10. JavaScript innerTHML和createElement效率对比

    前言: 在DOM节点操作中,innerTHML和createElement都可以实现创建元素.它们实现的功能类似,但是效率却相差很大.本文分别统计用innerTHML字符串拼接方式.innerTHML ...