我是靠谱客的博主 机智音响,最近开发中收集的这篇文章主要介绍每天一点面试题(3),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

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

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. 直接调用函数
	let obj = {
	  a: function() {
	    console.log(this);
	  }
	}
	let func = obj.a;
	func();

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

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

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

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

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

首先什么是拷贝?

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

	let arr = [1, 2, 3];
	let newArr = arr;
	newArr[0] = 100;
	
	console.log(arr);//[100, 2, 3]

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

	let arr = [1, 2, 3];
	let newArr = arr.slice();
	newArr[0] = 100;
	
	console.log(arr);//[1, 2, 3]

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

这就是浅拷贝!

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

	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. 手动实现
   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() 拷贝的是对象的属性的引用,而不是对象本身。
   let obj = { name: 'sy', age: 18 };
   const obj2 = Object.assign({}, obj, {name: 'sss'});
   console.log(obj2);//{ name: 'sss', age: 18 }
  1. concat浅拷贝数组
   let arr = [1, 2, 3];
   let newArr = arr.concat();
   newArr[1] = 100;
   console.log(arr);//[ 1, 2, 3 ]
  1. slice浅拷贝
  2. …展开运算符
   let arr = [1, 2, 3];
   let newArr = [...arr];//跟arr.slice()是一样的效果

最后

以上就是机智音响为你收集整理的每天一点面试题(3)的全部内容,希望文章能够帮你解决每天一点面试题(3)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部