zoukankan      html  css  js  c++  java
  • 面试 05-01.创建对象和原型链

    05-01.创建对象和原型链

    #前言

    #面向对象的三大特性

    • 封装

    • 继承

    • 多态

    #原型链的知识

    原型链是面向对象的基础,是非常重要的部分。有以下几种知识:

    • 创建对象有几种方法

    • 原型、构造函数、实例、原型链

    • instanceof的原理

    • new 运算符

    #创建对象有几种方法

    #方式一:字面量

        var obj11 = {name: 'qianguyihao'};
        var obj12 = new Object(name: 'qianguyihao'); //内置对象(内置的构造函数)
    
     

    上面的两种写法,效果是一样的。因为,第一种写法,obj11会指向Object

    • 第一种写法是:字面量的方式。

    • 第二种写法是:内置的构造函数

    #方式二:通过构造函数

        var M = function (name) {
            this.name = name;
        }
        var obj3 = new M('smyhvae');
    
     

    #方法三:Object.create

        var p = {name:'smyhvae'};
        var obj3 = Object.create(p);  //此方法创建的对象,是用原型链连接的
    
     

    第三种方法,很少有人能说出来。这种方式里,obj3是实例,p是obj3的原型(name是p原型里的属性),构造函数是Objecet 。

    #原型、构造函数、实例,以及原型链

    PS:任何一个函数,如果在前面加了new,那就是构造函数。

    #原型、构造函数、实例三者之间的关系

    • 1、构造函数通过 new 生成实例

    • 2、构造函数也是函数,构造函数的prototype指向原型。(所有的函数有prototype属性,但实例没有 prototype属性)

    • 3、原型对象中有 constructor,指向该原型的构造函数。

    上面的三行,代码演示:

        var Foo = function (name) {
            this.name = name;
        }
    
        var foo = new Foo('smyhvae');
    
     

    上面的代码中,Foo.prototype.constructor === Foo的结果是true

    • 4、实例的__proto__指向原型。也就是说,foo.__proto__ === Foo.prototype

    声明:所有的引用类型(数组、对象、函数)都有__proto__这个属性。

    Foo.__proto__ === Function.prototype的结果为true,说明Foo这个普通的函数,是Function构造函数的一个实例。

    #原型链

    原型链的基本原理:任何一个实例,通过原型链,找到它上面的原型,该原型对象中的方法和属性,可以被所有的原型实例共享。

    Object是原型链的顶端。

    原型可以起到继承的作用。原型里的方法都可以被不同的实例共享:

        //给Foo的原型添加 say 函数
        Foo.prototype.say = function () {
            console.log('');
        }
    
     

    原型链的关键:在访问一个实例的时候,如果实例本身没找到此方法或属性,就往原型上找。如果还是找不到,继续往上一级的原型上找。

    #instanceof的原理

    instanceof的作用:用于判断实例属于哪个构造函数。

    instanceof的原理:判断实例对象的__proto__属性,和构造函数的prototype属性,是否为同一个引用(是否指向同一个地址)。

    注意1:虽然说,实例是由构造函数 new 出来的,但是实例的__proto__属性引用的是构造函数的prototype。也就是说,实例的__proto__属性与构造函数本身无关。

    注意2:在原型链上,原型的上面可能还会有原型,以此类推往上走,继续找__proto__属性。这条链上如果能找到, instanceof 的返回结果也是 true。

    比如说:

    • foo instance of Foo的结果为true,因为foo.__proto__ === Foo.prototype为true。

    • foo instance of Objecet的结果也为true,因为Foo.prototype.__proto__ === Object.prototype为true。

    但我们不能轻易的说:foo 一定是 由Object创建的实例。这句话是错误的。我们来看下一个问题就明白了。

    #分析一个问题

    问题:已知A继承了B,B继承了C。怎么判断 a 是由A直接生成的实例,还是B直接生成的实例呢?还是C直接生成的实例呢?

    分析:这就要用到原型的constructor属性了。

    • foo.__proto__.constructor === Foo的结果为true,但是 foo.__proto__.constructor === Object的结果为false。

    所以,用 consturctor判断就比用 instanceof判断,更为严谨。

    #new 运算符

    当new Foo()时发生了什么:

    (1)创建一个新的空对象实例。

    (2)将此空对象的隐式原型指向其构造函数的显示原型。

    (3)执行构造函数(传入相应的参数,如果没有参数就不用传),同时 this 指向这个新实例。

    (4)如果返回值是一个新对象,那么直接返回该对象;如果无返回值或者返回一个非对象值,那么就将步骤(1)创建的对象返回。

    参考《JS高程》6.2.2

    #类继承和原型继承的区别

  • 相关阅读:
    Codeforces Gym 100463D Evil DFS
    codeforces Gym 100187J J. Deck Shuffling dfs
    Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs
    Codeforces Round #306 (Div. 2) B. Preparing Olympiad dfs
    Codeforces Round #402 (Div. 2)D. String Game 二分
    hdu 4499 Cannon dfs
    cdoj 15 Kastenlauf dfs
    hdu5254 棋盘占领 dfs
    zoj 3620 Escape Time II dfs
    CDOJ 215 吴队长征婚 DFS+剪枝
  • 原文地址:https://www.cnblogs.com/yzy521/p/14133308.html
Copyright © 2011-2022 走看看