美文网首页
JS面试题

JS面试题

作者: 裁尘的人儿 | 来源:发表于2020-08-06 18:38 被阅读0次

    1. JS原型链

    • 一个对象除了有自己定义的属性,还有一个属性“_proto_”(它是一个对象),"obj._proto_"里也有很多属性,包括valueOf、 toString、 constructor等……


      图片.png
    • “obj._proto_”其实也有一个叫_proto_的属性(但是一般值为null)

    • obj之所以可以拥有valueOf、 toString、 constructor这几个属性,是跟“._proto_”有关:
      当我们「读取」 obj.toString 时,JS 引擎会做下面的事情:

    1. 看看 obj 对象本身有没有 toString 属性。没有就走到下一步。
    2. 看看 obj.__proto__ 对象有没有 toString 属性,发现 obj.__proto__ 有 toString 属性,于是找到了
    所以 obj.toString 实际上就是第 2 步中找到的 obj.__proto__.toString。
    可以想象,
    3. 如果 obj.__proto__ 没有,那么浏览器会继续查看 obj.__proto__.__proto__
    4. 如果 obj.__proto__.__proto__ 也没有,那么浏览器会继续查看 obj.__proto__.__proto__.proto__
    5. 直到找到 toString 或者 __proto__ 为 null。
    上面的过程,就是「读」属性的「搜索过程」。
    而这个「搜索过程」,是连着由 __proto__ 组成的链子一直走的。
    

    这个链子,就叫做「原型链」。

    ## **共享原型链**
    
    现在我们有另一个对象
    
    

    var obj2 = { name: 'obj2' }

    如图:

    image

    那么 obj.toString 和 obj2.toString 其实是同一个东西,也就是 obj2.proto.toString。

    这有什么意义呢?

    如果我们改写 obj2.proto.toString,那么 obj.toString 其实也会变!

    这样 obj 和 obj2 就是具有某些相同行为的对象,这就是意义所在。

    差异化

    如果我们想让 obj.toString 和 obj2.toString 的行为不同怎么做呢?

    直接赋值就好了:

    obj.toString = function(){ return '新的 toString 方法' }
    
    image

    总结:

    「读」属性时会<u style="border-bottom-color: grey; border-bottom-style: dashed; border-bottom-width: 1px; text-decoration: none;">沿着原型链搜索</u>

    2. 利用filter结合indexOf,可以巧妙地去除Array的重复元素:

    deleteRepElements() {
        var newPhotos, oldPhotos = ['x1', 'x2', 'x3', 'x2', 'x3', 'x4'];
        newPhotos = oldPhotos.filter(function (element, index, self) {
            return self.indexOf(element) === index;
        });
        console.log(newPhotos)
    }
    

    其中: element, index, self是filter里callback的三个输入参数,固定参数(不能该名字),默认代表:
    var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

    参数:
    1. callback
      用于测试数组的每个元素,返回true保留元素,否则返回false。
      它接受三个参数:
      1. element
        数组中正在处理的当前元素。
      2. index
        数组中正在处理的当前元素的索引。
      3. array
        召唤出滤波器的这个数组。
    2. thisArg
      执行回调时用作此值的值。

    3. 给 Array 对象添加新的方法/函数:以后任何一个数组都会拥有这个新函数

     Array.prototype.duplicator = function() {
     let s = this.concat(this) 
       return s
     }
     let t = [1,2,3,4,5].duplicator()
     console.log(t) // [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    

    4. apply方法和call方法:

    • apply方法:是将其他对象里的属性/方法添加到自己对象里
      如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:
    blackCat.say.call(whiteDog);
    //这就是将blackCat对象的say方法添加whiteDog对象里。从此我们的whiteDog就有say方法了。
    

    所以,可以看出call和apply是为了动态改变this而出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。
    用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过:
    var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
    这样domNodes就可以应用Array下的所有方法了。

    5. JS合并两个数组的方法

    var array = ["football", "basketball"];
     var array2 = ["volleyball", "golfball"];
     var i = Array.prototype.push.apply(array,array2);
     console.log(array); // ["football", "basketball", "volleyball", "golfball"]
     console.log(i); // 4
    
    

    相关文章

      网友评论

          本文标题:JS面试题

          本文链接:https://www.haomeiwen.com/subject/heuyrktx.html