我是靠谱客的博主 机智音响,这篇文章主要介绍每天一点面试题(3),现在分享给大家,希望可以做个参考。

1.模拟实现一个 bind 的效果

实现bind之前,我们首先要知道它做了哪些事情。
1. 对于普通函数,绑定this指向
2. 对于构造函数,要保证原函数的原型对象上的属性不能丢失

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Function.prototype.bind = function (context, ...args) { // 异常处理 if (typeof this !== "function") { throw new Error("Function.prototype.bind error"); } // 保存this的值,它代表调用 bind 的函数 var self = this; var fNOP = function () {}; var fbound = function () { self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments))); } fNOP.prototype = this.prototype; fbound.prototype = new fNOP(); return fbound; }

2.谈谈你对JS中this的理解

其实JS中的this是一个非常简单的东西,只需要理解它的执行规则就OK。
call/apply/bind可以显示绑定, 这里就不说了。
主要这些场隐式绑定的场景讨论:
1.全局上下文
1.直接调用函数
3.对象.方法的形式调用
4.DOM事件绑定(特殊)
5.new构造函数绑定
6.箭头函数

  1. 全局上下文
    全局上下文默认this指向window, 严格模式下指向undefined。
  2. 直接调用函数
复制代码
1
2
3
4
5
6
7
8
let obj = { a: function() { console.log(this); } } let func = obj.a; func();

这种情况是直接调用。this相当于全局上下文的情况。

  1. 对象.方法的形式调用
    还是刚刚的例子,我如果这样写:
复制代码
1
2
obj.a();

这就是对象.方法的情况,this指向这个对象

  1. DOM事件绑定
    onclick和addEventerListener中 this 默认指向绑定事件的元素。
    IE比较奇异,使用attachEvent,里面的this默认指向window。
  2. new+构造函数
    此时构造函数中的this指向实例对象。
  3. 箭头函数
    箭头函数没有this, 因此也不能绑定。里面的this会指向当前最近的非箭头函数的this,找不到就是window(严格模式是undefined)。比如:
复制代码
1
2
3
4
5
6
7
8
9
10
let obj = { a: function() { let do = () => { console.log(this); } do(); } } obj.a(); // 找到最近的非箭头函数a,a现在绑定着obj, 因此箭头函数中的this是obj

3.JS中浅拷贝的手段有哪些?

首先什么是拷贝?

首先来直观的感受一下什么是拷贝。

复制代码
1
2
3
4
5
6
let arr = [1, 2, 3]; let newArr = arr; newArr[0] = 100; console.log(arr);//[100, 2, 3]

这是直接赋值的情况,不涉及任何拷贝。当改变newArr的时候,由于是同一个引用,arr指向的值也跟着改变。
现在进行浅拷贝:

复制代码
1
2
3
4
5
6
let arr = [1, 2, 3]; let newArr = arr.slice(); newArr[0] = 100; console.log(arr);//[1, 2, 3]

当修改newArr的时候,arr的值并不改变。什么原因?
因为这里newArr是arr浅拷贝后的结果,newArr和arr现在引用的已经不是同一块空间啦!

这就是浅拷贝!

但是这又会带来一个潜在的问题:

复制代码
1
2
3
4
5
6
let arr = [1, 2, {val: 4}]; let newArr = arr.slice(); newArr[2].val = 1000; console.log(arr);//[ 1, 2, { val: 1000 } ]

咦!不是已经不是同一块空间的引用了吗?为什么改变了newArr改变了第二个元素的val值,arr也跟着变了。

这就是浅拷贝的限制所在了。 它只能拷贝一层对象。如果有对象的嵌套,那么浅拷贝将无能为力。 但幸运的是,深拷贝就是为了解决这个问题而生的,它能 解决无限极的对象嵌套问题,实现彻底的拷贝。当然,这是我们下一篇的重点。 现在先让大家有一个基本的概念。

接下来,我们来研究一下JS中实现浅拷贝到底有多少种方式?

  1. 手动实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const shallowClone = (target) => { if (typeof target === 'object' && target !== null) { const cloneTarget = Array.isArray(target) ? []: {}; for (let prop in target) { if (target.hasOwnProperty(prop)) { cloneTarget[prop] = target[prop]; } } return cloneTarget; } else { return target; } }
  1. Object.assign
    但是需要注意的是,Object.assgin() 拷贝的是对象的属性的引用,而不是对象本身。
复制代码
1
2
3
4
let obj = { name: 'sy', age: 18 }; const obj2 = Object.assign({}, obj, {name: 'sss'}); console.log(obj2);//{ name: 'sss', age: 18 }
  1. concat浅拷贝数组
复制代码
1
2
3
4
5
let arr = [1, 2, 3]; let newArr = arr.concat(); newArr[1] = 100; console.log(arr);//[ 1, 2, 3 ]
  1. slice浅拷贝
  2. …展开运算符
复制代码
1
2
3
let arr = [1, 2, 3]; let newArr = [...arr];//跟arr.slice()是一样的效果

最后

以上就是机智音响最近收集整理的关于每天一点面试题(3)的全部内容,更多相关每天一点面试题(3)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部