• 2020 年我碰到的原型链的面试题.md


    写作背景

    猛然间发现都需要在牛客网上视频面试了。

    好气人呀,一周内面试笔者居然再原型链问题上被连续绊倒两次,然后被判定为 JS 基础薄弱。真的好气人呀,所以笔者研究了一下午的原型链,打算之后再也不会被这个绊倒,其遇到的题目和大家分享。

    题目

    • 题目1,来自快手
    Function.prototype.a = () => {
      console.log(1);
    }
    Object.prototype.b = () => {
      console.log(2);
    }
    function A() {}
    const a = new A();
    
    a.a();
    a.b();
    A.a();
    A.b();
    
    

    真的再很多地方出现了,我一搜才发现其他朋友在 JD 的面试上也遇到过。我遇到的当晚也写了一份解答思路:面试:Function.prototype.a 请给出下列函数的执行输出

    对于 new 出来的对象 a 的属性,原型链查找的顺序应该是

    1. a 自身
    2. `a.__proto__` 相当于 A.prototype
    3. `A.prototype.__proto__` 相当于 Object.prototype
    4. `Object.prototype.__proto__` 这个为 null,原型链查找到头。
    

    对于 function 定义的函数 A 的属性,原型链查找顺序应该是

    1. A 自身
    2. `A.__proto__` 相当于 Function.prototype
    3. `Function.prototype.__proto__` 等于 Object.prototype
    4. `Object.prototype.__proto__` 这个为 null,原型链查找到头。
    

    • 题目2,来自网易云音乐
    function A() {
    }
    
    A.prototype.n = 0;
    
    A.prototype.add = function () {
      this.n += 1;
    }
    
    a = new A();
    b = new A();
    a.add();
    console.log(b.add())
    

    这是在快手后的网易面试,自从有了题1,我对这一套就开始疑神疑鬼的,想的复杂了。

    构造函数 new 出来的对象,其方法 this 都指向他的实例。所以调用完 add 方法,遇到 this.n += 1;,这个 this 指向的又是实例对象。所以我们的 a 对象 和 b 对象都有独属于自己的 n。

    • 题目3
    function Person(name, age) {
      this.name = name;
      this.age = age;
      this.eat = function() {
        console.log(age + "岁的" + name + "在吃饭。");
      }
    }
    
    Person.run = function () {}
    Person.prototype.walk = function () {}
    
    let p1 = new Person("jsliang", 24);
    let p2 = new Person("jsliang", 24);
    
    console.log(p1.eat === p2.eat); // false
    console.log(p1.run === p2.run); // true
    console.log(p1.walk === p2.walk); // true
    

    new 操作符使得构造函数内的 eat 函数(对象),是在堆中新开一份空间放置,所以两个实例对象它自然不共享。

    而原型上两个实例对象自然都是同一份,walk 方法相同。

    需要注意的是 p1.run 和 p2.run 都是 undefined。因为 run 方法只是作为 Person 自己的静态属性,p1 和之后的原型链上是找不到的。

    • 题目4
    function A() {
      this.test = 1
    }
    
    var a = new A();
    a.test
    
    a = new A;
    a.test
    
    a = A()
    a.test
    
    A.test
    

    提示读者们,的是 new A 等价与 new A(),MDN上这么说

    使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。

    a = A() 只是把 A 作为普通函数执行了,这个普通函数内部并无 return 出什么来,所以 a 只是 undefined,a.test 就会报错。

    至于 A.test, A 只是个函数定义,A 本身没得到执行,自然不会有什么 test 属性,只能往 Function.prototype 上找,自然还是找不到了。

    要是 Java 后三个都得报语法错误,我开始没那么喜欢 JS 了。

    • 题5
    function A() {}
    function B(a) {
        this.a = a;
    }
    function C(a) {
        if (a) {
            this.a = a;
        }
    }
    A.prototype.a = 1;
    B.prototype.a = 1;
    C.prototype.a = 1;
    
    console.log(new A().a); // 1
    console.log(new B().a); // undefined
    console.log(new C(2).a); // 2
    

    console.log(new B().a); // undefined,你需要知道此时 B 它自身属性里已经有了一个 a 属性了

    • 题6

    问 foo1 上究竟都挂着什么属性

    function foo() {
        this.some = '222'
        let ccc = 'ccc'
        foo.obkoro1 = 'obkoro1'
        foo.prototype.a = 'aaa'
    }
    foo.koro = '扣肉'
    foo.prototype.test = 'test'
    let foo1 = new foo() 
    foo.prototype.test = 'test2' 
    

    foo1 上挂着属性 some,其原型链上挂着 test 和 a,至于 foo.obkoro1 只是静态属性不影响 foo1,ccc 更是闭包里的变量更没关系。

    思考题

    • 原型链查找的终点在哪儿?
    • __proto__ 非标准,有什么能替代它获取原型链?
    • new 操作符做了什么?
    • 构造函数中的 this 指向何方?

    总结

    去年开始出门面试,那时候被卡的是框架源码和实现细节;之后就被问各种基建系统的实现;等年初出门面几家,发现全都做算法题了;等我花了一阵子把什么链表堆栈的 leetcode 题刷过,发现最近面的没有一个问算法题,却都在问这种 “JS 基础题”。面试真的是一门玄学,怎么准备都不够。

    哦,对了,还有 promise 微任务组合起来的输出的问题,也坑了我好多次,留给后面的篇幅吧。真的好讨厌这样的问题啊!

  • 相关阅读:
    Numpy用于数组的文件输入输出
    numpy利用数组进行数据处理
    numpy的通用函数:快速的元素级数组函数
    NumPy基础知识:数组和矢量计算
    数据处理任务介绍
    Django的ModelForm
    Http1.0和Http1.1的主要区别
    静态库中如何包含资源文件
    zt 正则
    oc调用swift的打包.a / framework 不成功?!
  • 原文地址:https://www.cnblogs.com/everlose/p/12944524.html
Copyright © 2020-2023  润新知