这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将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. 实战Docker容器调度

    目录 一.前言 二.Docker Compose 2.1.简介 2.2.下载安装 2.3.小实验 2.4.小实验的细节 2.5.Compose file的编写规则 三.Docker Swarm 3.1 ...

  2. 【JAVA】HashMap源码阅读

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

  3. Java8之日期处理

    简介 Java8除了有较大更新的 lambda. Stream ,还推出了全新的日期时间API.Java之前处理日期.日历和时间的不足之处主要有: 日期类型为可变类型,非线程安全使其应用非常受限 没有 ...

  4. kafka学习(五)Spring Boot 整合 Kafka

    文章更新时间:2020/06/08 一.创建Spring boot 工程 创建过程不再描述,创建后的工程结构如下: POM文件中要加入几个依赖: <?xml version="1.0& ...

  5. Mysql的ONLY_FULL_GROUP_BY

    今天在测试环境遇到一个问题,本地测试是没有问题,在测试环境sql报错了: nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntax ...

  6. Spring Boot 第三弹,一文带你了解日志如何配置?

    前言 日志通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节.但是,这丝毫不影响它在任何一个系统中的重要的地位. 今天就来介绍一下Spring Boot中的日志如何配置. Spr ...

  7. Centos-删除文件或目录-rm

    rm 删除目录或者文件,如果是链接文件,则只删除这个链接文件而不是链接指向的文件 相关选项 -r 递归删除目录 -f 忽略不存在提示和确认提示,本身确认提示系统默认添加-i参数 -i 删除文件前提示, ...

  8. Dell XPS 7590 Hackintosh

    网上主流引导Hackintosh的工具有Chameleon, Clover和OpenCore. 但是随着Hackintosh重要驱动开发团队acidanthera逐渐转向OpenCore,后者显然才是 ...

  9. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树上启发式合并(DSU ON TREE)

    题目描述 一棵根为\(1\) 的树,每条边上有一个字符(\(a-v\)共\(22\)种). 一条简单路径被称为\(Dokhtar-kosh\)当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求 ...

  10. 1.入门篇十分钟了解Spring Cloud

    文章目录 Spring Cloud入门系列汇总 为什么需要学习Spring Cloud 什么是Spring Cloud 设计目标与优缺点 设计目标 优缺点 Spring Cloud发展前景 整体架构 ...