精华内容
下载资源
问答
  • 这篇文章主要介绍了JavaScript原型继承原型链原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在讨论原型继承之前,先回顾一下关于创建自定义类型的...
  • 原型链是实现继承的一种基础方式,是原型搜索机制的扩展。本文以基本原理,代码实现,结构图解三种方式诠释,无论基础如何,都能通过本文对js原型链继承达到更深入的理解。


    原型链是实现继承的一种方式,扩展了原型搜索机制,使搜索可以继承向上,搜索原型的原型。

    一 原型搜索机制

    在原型搜索机制中,构造函数,实例,和原型对象的关系为,原型对象是构造函数的一个属性prototype,原型对象中有一个属性constructor指回构造函数,构造函数生成的实例中具有指针指向构造函数上的原型对象。

    1.1 代码实现

    // 构造函数
    function person(name, color){
        this.name = name;
        this.color = color;
    }
    // 向默认的原型对象中添加值
    person.prototype.getColor = function(){
        return this.color;
    }
    // 通过构造函数构建实例 实例中含有指向原型对象的指针
    var personOne = new person("tom", "red");
    
    console.log("来自构造函数中的属性", personOne.name) // "tom"
    console.log("来自原型对象中的属性", personOne.getColor()) // "red"
    

    1.2 结构图解

    构造函数,原型对象,实例的关系如下。

    在这里插入图片描述

    1.3 搜索机制

    当搜索一个属性/方法时,先搜索实例本身,如果实例本身没有找到,再从指针找到其指向的原型对象,向上查找的特性与作用域链相似。

    也就是说,如果在实例中设置了要查找的属性名,就不会再向上查找。

    ... ...
    personOne.getColor = function(){
    	return "实例中的属性";
    }
    console.log(personOne.getColor()); // "实例中的属性"
    ... ...
    

    这时候如果没找到,并且该原型对象中也有一个指向另一个原型对象的指针,就从指针向上搜索原型的原型,直到原型链的末端,也就是原型不再包含指向另一个原型的指针为止。

    二 原型链代码实现

    从这里看出,原型链是由指向原型对象的指针将多个原型对象连接起来,上面指出,当我们new一个A实例,实例中就包含一个指向原型对象的指针。

    如果我们将该实例赋值为另外一个对象实例B的原型对象,原型链就构成了,查找顺序为。
    B 实 例 − > B 原 型 ( A 实 例 ) − > A 原 型 B实例->B原型(A实例)->A原型 B>B(A)>A

    2.1 代码实现

    在下面的代码中,访问objB的实例对象obj时,通过原型链,最终输出了objA的原型对象中的值。

    function objA(){
        this.title = 'A';
    }
    
    objA.prototype.name = "objA-prototype";
    
    function objB(){
        this.title = 'B';
    }
    
    objB.prototype = new objA();
    
    var obj = new objB;
    console.log(obj.name); // objA-prototype
    

    2.2 结构图解

    在这里插入图片描述

    2.3 链条拓展

    我们可以通过将B实例替换C对象实例的原型对象的方式来拓展该原型链。拓展后查找顺序为。
    C 实 例 − > C 原 型 ( B 实 例 ) − > B 原 型 ( A 实 例 ) − > A 原 型 C实例->C原型(B实例)->B原型(A实例)->A原型 C>C(B)>B(A)>A
    原型链就是这样实现继承的。

    在上面公式中,在C实例向A原型搜索的过程中,只要在某一个地方获得了一个同名属性,就会取该属性,而不再向上搜索,也就是说,在下层原型中添加上层原型链已有的方法会覆盖方法。

    三 原型链的缺点

    原型链也有一些缺点,如原型链中的属性是共享的,当修改某一个原型对象中的值时,下层所以实例在获取该值时都会变化,因为大家都是通过指针读取原型对象中的值。

    由于这种缺陷,一般不单独使用原型链继承。

    有一些缺点,如原型链中的属性是共享的,当修改某一个原型对象中的值时,下层所以实例在获取该值时都会变化,因为大家都是通过指针读取原型对象中的值。

    由于这种缺陷,一般不单独使用原型链继承。

    其他的继承方法请关注本专栏,等待后续文章。

    展开全文
  • JS原型链继承

    千次阅读 2019-01-09 18:23:43
    再讲述JS原型链继承之前,我希望大家能够先理解 《函数,函数原型和函数实例之间的关系》,这样有助于大家理解JS原型链继承原理,下面先看一张图吧,咱们看图说话: 如果大家看完了 《函数,函数原型和函数实例...

    再讲述JS原型链继承之前,我希望大家能够先理解 《函数,函数原型和函数实例之间的关系》,这样有助于大家理解JS原型链继承的原理,下面先看一张图吧,咱们看图说话:
    JS原型链继承

    如果大家看完了 《函数,函数原型和函数实例之间的关系》 这篇文章,应该多少能明白原型链继承的原理了。

    如上图所示: Personal 对象想要继承 Main 对象,则通过将 Main 的实例赋值给 Personal 的原型对象 :

    Personal.prototype = new Main () ;
    

    如此 Personal原型对象 就能通过 Main 对象的实例中的 [[Prototype]] 来访问到 Main原型对象 中的属性和方法了,而此时大家注意,Personal原型对象 则与 Personal函数 断开了联系,因为Personal原型对象被重新赋值了,所以还需要重新将Personal函数Personal原型对象建立联系:

    Personal.prototype.constructor = Personal ;
    

    完整代码如下:

    function Main () {
    }
    Main.prototype.sex = '男' ;
    Main.prototype.eat = function () {
    	console.log('Main eat ...')
    }
    
    
    function Personal () {}
    Personal.prototype.name = 'hwk';
    Personal.prototype.sayName = function () {
    	console.log('Personal name')
    }
    
    // 继承
    Personal.prototype = new Main();
    Personal.prototype.constructor = Personal;
    
    var p = new Personal();
    console.log(p.sex ) ; // 男
    console.log(p.name) ; // undefined
    p.eat();			  // Main eat ...
    p.sayName ();		  // Uncaught TypeError:p.sayName is not a function 
    

    运行如上代码你会发现 p.nameundefined , p.sayName 这个方法没找到,原因在于我们后面重新赋值了 Personal.prototype = new Main(); 因此找不到一开始定义在 Personal.prototype 上的name属性和sayName方法,因此在使用原型链继承的时候,要在继承之后再去在原型对象上定义自己所需的属性和方法:

    // 先继承
    Personal.prototype = new Main();
    Personal.prototype.constructor = Personal;
    
    // 后定义属性和方法
    Personal.prototype.name = 'hwk';
    Personal.prototype.sayName = function () {
    	console.log('Personal name')
    }
    
    // 正确输出
    console.log(p.sex ) ; // 男
    console.log(p.name) ; // hwk
    p.eat();			  // Main eat ...
    p.sayName ();		  // Personal name
    

    此时 Personal的实例 已经可以访问到父类Main原型对象中的方法和属性了,这也就是原型链继承的方式,希望对大家有帮助!

    PS:在原型对象上定义属性和方法,其所有的构造函数实例都能共享原型上的属性和方法,因此如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象。

    展开全文
  • 和其他的面向对象编程语言不同,最开始js并没有引入class的概念,但是js中有在大量使用对象,为了保证对象之间的联系,JavaScript引入了原型与原型链的概念。 1、什么是原型 在js中,每一个构造函数都拥有一个...

    1、js中的原型和原型链

    和其他的面向对象编程语言不同,最开始js并没有引入class的概念,但是js中有在大量使用对象,为了保证对象之间的联系,JavaScript引入了原型与原型链的概念。

    1.1、什么是原型

    在js中,每一个构造函数都拥有一个prototype属性,这个属性指向一个对象,也就是原型对象。原型对象默认拥有一个constructor属性,指向指向它的那个构造函数,每个对象都拥有一个隐藏的属性[[prototype]],指向它的原型对象。原型对象就是用来存放实例中共有的那部分属性。

    1.2. 什么是原型链

    js中所有的对象都是由它的原型对象继承而来。而原型对象自身也是一个对象,它也有自己的原型对象,这样层层上溯,就形成了一个类似链表的结构,这就是原型链, 所有原型链的终点都是Object函数的prototype属性.

    1.3. 常见的题目

    Array.__proto__ ===  Function.prototype  // true
    Array.__proto__.__proto__ === Object.prototype  // true
    Function.prototype.__proto__ === Object.prototype  // true
    
    
    function F(){}
    Function.prototype.a = function(){
    	console.log('a1')
    }
    Function.prototype.b = function(){
    	console.log('b1')
    }
    Object.prototype.a = function(){
    	console.log('a2')
    }
    Object.prototype.b = function(){
    	console.log('b2')
    }
    let f = new F()
    f.a()
    f.b()
    F.a()
    F.b()
    

    2、js中的继承

    js主要存在6种继承方式。

    2.1 原型链继承

    function Parent(){
        this.parent = [1,2,3]
    }
    Parent.prototype.getName = function(){
        console.log(this.parent)
    }
    function Child(child){
        this.child = child
    }
    
    Child.prototype = new Parent()
    Child.prototype.constructor = Child
    

    优点:

    • 这种方式的优点很明显,多个实例可以共享原型链上定义的属性和方法。

    缺点:

    • 每个实例对引用类型的属性的修改也会被其他实例共享,这不是我们想看到的
    • 创建child的时候无法像构造函数传参,child实例无法初始化父类属性

    2.1 构造函数继承

    function Parent(parent){
        this.parent = parent
    }
    Parent.prototype.getName = function(){
        console.log(this.parent)
    }
    function Child(name,child){
        Parent.call(this,name)
        this.child = child
    }
    

    优点:

    • 克服了原型链继承带来的2个缺点

    缺点:

    • 子类无法继承父类原型链上的方法;
    • 每次生成子类实例都会执行一次父函数

    2.2 组合继承(常用的一种方式)

    function Parent(parent){
        this.parent = parent
    }
    Parent.prototype.getName = function(){
        console.log(this.parent)
    }
    function Child(name,child){
        Parent.call(this,name)
        this.child = child
    }
    Child.prototype = new Parent()
    Child.prototype.constructor = Child
    

    优点:解决了上面两种方法的缺点

    • 子类的构造函数会代替原型上的那个父类构造函数
    • 每个新实例引入的构造函数属性是私有的

    缺点:

    • 父类的构造函数执行两次Parent.call(this,name)/new Parent()
    • 子类的构造函数会代替原型上的那个父类构造函数

    2.4 寄生组合继承(常用)

    function Parent(parent){
        this.parent = parent
    }
    Parent.prototype.getName = function(){
        console.log(this.parent)
    }
    function Child(name,child){
        Parent.call(this,name)
        this.child = child
    }
    
    function inheritPrototype(Parent, Child){
         //创建父类原型的一个副本,把副本赋值给子类原型,而不是new Parent(),减少一次父构造函数的调用
        Child.prototype = Object.create(Parent.prototype)
    	Child.prototype.constructor = Child
    }
    

    解决了组合继承中父类构造函数执行两次的问题

    继承扩展的知识点

    1. 是Object.create的原理
    Object.create => function(obj){
          var f = function(){};
          f.prototype = obj;
          return new f();
    }
    

    先在内部创建一个空构造函数
    把构造函数的原型指向传进来的obj对象
    通过new创建对象并返回

    2. Object.create,new Object(), {}三个的区别(百度)

    Object.create是使用指定的原型proto对象及其属性properties去创建一个新的对象,也就是我们新建的对象的原型对象是传入create的对象。
    值得注意的是当create的参数为null的时候创建的新对象完全是一个空对象,没有原型,也就是没有继承Object.prototype上的方法。

    new Object()和{}本质上没有区别,它们创建的新对象的原型指向的是 Object.prototype。

    new Object()和{}在初始化的过程上有区别,前者是用构造函数实例化对象,后者是直接创建JSON对象,后者的初始化比较方便,可以在初始化的时候同时赋值。而两种方法创建的对象在使用上都是一样的,所以使用的时候都建议用后者,没有new的过程比较高效。

    3. new的原理
    function myNew () {
        //创建一个实例对象
        let obj = new Object()
        //传入构造函数
        let fn = Array.prototype.shift.call(arguments)
        let args = Array.prototype.slice.call(arguments,1)
        //实现继承
        obj.__proto__ = fn.prototype
        //调用构造器,改变this指向到实例
        let result = fn.apply(obj,args)
        return typeof result === 'object' ? result : obj
    }
    
    • 创建一个新对象
    • 将构造函数的作用域赋给新对象
    • 调用构造器,改变this指向到实例,执行构造函数中的代码(为这个新对象添加属性)
    • 返回新对象。
    展开全文
  • JavaScript原型链继承

    2021-11-21 14:22:33
    一、Javascript原型链 要讲解Javascript原型链我们首先要弄明白几个名词。prototype、__proto__、constructor、原型链。 1、prototype 在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象...

    一、Javascript原型链

    要讲解Javascript原型链我们首先要弄明白几个名词。prototype、__proto__、constructor、原型链。

    1、prototype

    在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。
    原型的概念:每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。
    举个例子:

    function Person(age){
    	this.age = age;
    }
    Person.prototype.name = "wenhua"
    var person1 = new Person()
    var person2 = new Person()
    console.log(person1.name)	//wenhua
    console.log(person2.name)	//wenhua
    

    上面的例子可以看出Person构造函数本身没有name属性,但是他构造的实例却可以继承该属性。原因是在Person构造函数在创建的时候,会关联一个对象(原型对象),每个对象都会从原型中"继承"属性。

    2、__proto__

    这是每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型。但是值得注意的是__proto__是一个绝大多数浏览器都支持的非标准方式,也可以借助ES6中Object.getPrototypeOf(obj)实现。
    举个例子:

    function Person() {
    
    }
    var person = new Person();
    console.log(person.__proto__ === Person.prototype); // true
    console.log(Object.getPrototypeOf(person) === Person.prototype); // true
    

    在这里插入图片描述

    3、constructor

    每个原型都有一个constructor属性,指向该关联的构造函数。
    举个例子:

    function Person() {
    
    }
    console.log(Person===Person.prototype.constructor)  //true
    

    在这里插入图片描述
    下面再举个例子,说明之前三个的关系:

    function Person (){
    
    }
    var person = new Person()
    
    console.log(person.__proto__ == Person.prototype)	//true
    console.log(person.__proto__.constructor == Person)	//true
    console.log(person.constructor == Person)	//true
    

    4、原型链

    当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
    举个例子:

    function Person(){
    	
    }
    Person.prototype.name = 'wenhua'
    var person = new Person()
    person.name = 'liu'
    console.log(person.name)  //liu
    delete person.name;
    console.log(person.name)  //wenhua
    Object.defineProperty(Object.prototype,'name',{
    	value:'zhangsan'
    })
    delete Person.prototype.name
    console.log(person.name)	//zhangsan
    

    在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 liu。
    但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 wenhua。
    当我们删除了Person.prototype.name属性时,再读取person.name时就会继续往顶层找直到Object.prototype为止。首先找的顺序时实例自身,然后是实例的原型Person.prototype,再然后是实例原型的原型Object.prototype中查找。如果还没有找到那么久返回null。
    以下时关系图:
    在这里插入图片描述
    通常来说Object.prototype.__proto__的值是null,代表着对象的原型链终点,它表示着Object.prototype对象没有原型。
    举个例子:

    console.log(Object.prototype.__proto__ === null) // true
    

    在这里插入图片描述
    所以我们更新关系图为:
    在这里插入图片描述

    二、Javascript继承

    javascript的继承主要有以下其中方式。在这里我将列出以下其中的优劣点。

    首先提供一个父类:

    function People(name){
        // 属性
        this.name = name || 'Annie'
        // 实例方法
        this.sleep = function(){
            console.log(this.name + ' is sleeping ');
        }
    }
    // 原型方法
    People.prototype.eat = function(food){
        console.log(this.name + ' is eating ' + food);
    }
    

    1、原型链继承

    // 原型链继承

    function Woman(){
    }
    Woman.prototype = new People()
    Woman.prototype.name = 'Mark'
    let womanObj = new Woman()
    
    womanObj.sleep()
    womanObj.eat("fish")
    console.log(womanObj.name);
    

    在这里插入图片描述

    重点:
    让新实例的原型等于父类的实例。

    特点:
    1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)

    缺点:
    1、新实例无法向父类构造函数传参。
    2、继承单一。
    3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)

    2、借助构造函数继承(经典继承)

    // 借助构造函数继承(经典继承)
    function Woman(name){
        People.call(this)
        this.name = name || 'lucy'
    }
    let womanObj = new Woman()
    womanObj.sleep()
    // 不能继承原型属性/方法,只能继承父类的实例属性和方法
    // womanObj.eat()
    console.log(womanObj.name);
    

    在这里插入图片描述

    重点:
    用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))

    特点:
    1、只继承了父类构造函数的属性,没有继承父类原型的属性。
    2、解决了原型链继承缺点1、2、3。
    3、可以继承多个构造函数属性(call多个)。
    4、在子实例中可向父实例传参。

    缺点:
    1、只能继承父类构造函数的属性,不能继承父类原型链上的方法和属性。
    2、无法实现构造函数的复用。(每次用每次都要重新调用)
    3、每个新实例都有父类构造函数的副本,臃肿。

    3、组合式继承(组合原型链继承和借用构造函数继承)

    // 组合式继承
    function Woman(name){
        // this.age = age || 22
        People.call(this, name)//第二次调用People构造函数  子类型构造函数内部。
        this.age = 22
    }
    Woman.prototype = new People()
    Woman.prototype.constructor = Woman  //第一次调用People构造函数  创建子类型原型的时候
    let womanObj = new Woman('ren')
    
    womanObj.sleep()
    womanObj.eat("fish")
    console.log(womanObj.name);
    console.log(womanObj.age);
    

    在这里插入图片描述

    在举个例子,非常经典。

    function SuperType(name){
     this.name = name;
     this.colors = ["red", "blue", "green"];
    }
    SuperType.prototype.sayName = function(){
     alert(this.name);
    }
    
    function SubType(name, age){
     SuperType.call(this, name);  //第二次调用SuperType()
     
     this.age = age;
    }
    SubType.prototype = new SuperType();  //第一次调用SuperType()
    SubType.prototype.sayAge = function(){
     alert(this.age);
    }
    

    在第一次调用SuperType构造函数时,SubType.prototype会得到两个属性: name和colors; 他们都是SuperType的实例属性,只不过现在位于SubType的原型中。

    当调用SubType构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上创建了实例属性name和colors。

    于是这两个属性就屏蔽了原型中的两个同名属性。

    重点:
    结合了两种模式的优点,传参和复用

    特点:
    1、可以继承父类原型上的属性,可以传参,可复用。
    2、每个新实例引入的构造函数属性是私有的。

    缺点:
    调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。

    4、实例继承(原型式继承)

    // 实例继承(原型式继承)
    // 先封装一个函数容器,用来输出对象和承载继承的原型
    function Woman(obj){
       function F(){this.name = 'Bob'}
       F.prototype = obj  //继承了传入的参数
       return new F()  //返回函数对象
    }
    var instance = new People();
    let womanObj = new Woman(instance);  //拿到父类的实例
    
    womanObj.sleep()
    womanObj.eat("fish")
    console.log(womanObj.name);  //继承了父类函数的属性
    

    在这里插入图片描述

    重点:
    用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。

    特点:
    类似于复制一个对象,用函数来包装。

    缺点:
    1、所有实例都会继承原型上的属性。
    2、无法实现复用。(新实例属性都是后面添加的)

    5、寄生式继承

    在cnblog中找到的,这个例子非常的生动形象。

    // 与寄生构造函数和工厂模式类似,创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象。
    function createAnother(original){
        var clone = Object.create(original);    //通过调用函数创建一个新对象
        clone.sayHi = function(){               //以某种方式来增强这个对象
            console.log("Hi");
        };
        return clone;                        //返回这个对象
    }
    
    var person = {
        name: "Bob",
        friends: ["Shelby", "Court", "Van"]
    };
    
    var anotherPerson = createAnother(person);
    anotherPerson.sayHi();
    console.log(anotherPerson.name);
    console.log(anotherPerson.friends);
    // createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。
    // anotherPerson是基于person创建的一个新对象,新对象不仅具有person的所有属性和方法,还有自己的sayHi()方法。
    

    在这里插入图片描述

    6、组合寄生式继承

    function object(o){/*在ES5中规范了Object.create()方法*/
       function f(){}
       f.prototype = o;
       return new f();
    }
    
    /*
    function inheritPrototype(subType, superType){
     var protoType = Object.create(superType.prototype); //创建对象
     protoType.constructor = subType;     //增强对象
     subType.prototype = protoType;      //指定对象
    }
    */
    
    function inheritPrototype(subType,superType) {
        var _prototype = object(superType.prototype);  //创建对象
        _prototype.constructor = subType;  //增强对象
        subType.prototype = _prototype;   //指定对象
    }
    //超类构造函数
    function SupperType(name) {
        this.name = name;
        this.colors = ["red","blue","green"];
    }
    //设置超类原型函数
    SupperType.prototype.sayName = function() {
        console.log(this.name);
    };
    function SubType(name,age) {
        //调用超类的构造函数从而继承其属性
        SupperType.call(this,name);
        this.age = age;
    }
    //子类subType继承超类supperType
    inheritPrototype(SubType,SupperType);
    //子类的原型方法
    SubType.prototype.sayAge = function() {
        console.log(this.age);
    }
    //实例化子类
    var person1 = new SubType("李文",26);
    
    person1.sayName();
    

    在这里插入图片描述

    inheritPrototype函数接收两个参数:子类型构造函数和超类型构造函数。

    1. 创建超类型原型的副本。

    2. 为创建的副本添加constructor属性,弥补因重写原型而失去的默认的constructor属性

    3. 将新创建的对象(即副本)赋值给子类型的原型这种方法只调用了一次SuperType构造函数

    7、ES6继承

    // ES6继承
    class People{
        constructor(name ="wang", age = 27){
            this.name =name
            this.age = age
        }
        eat(){
            console.log(`${this.name} ${this.age} eat food`);
        }
        sleep(){
            console.log(`${this.name} is sleeping`);
        }
    }
    class Woman extends People{
        constructor(name = 'Alice', age = 22){
            super(name, age)
        }
        eat(){
            super.eat()
        }
        sleep(){
            console.log(`${this.name} is not sleeping, he is playing`);
        }
    }
    let womanObj = new Woman('jack');
    womanObj.sleep()
    womanObj.eat("fish")
    console.log(womanObj.name);
    

    在这里插入图片描述

    展开全文
  • 本文实例分析了Javascript原型链原理。分享给大家供大家参考,具体如下: 一、JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一...
  • JS原型链概况 JS的构造函数(即一普通的Function),可以理解为面向对象的一个Class, 这里就把Function都叫做Class吧。文字表现太生涩,没有图片理解形象。 function Father() { this.info = ["Zero"] } 图1-1 这个...
  • 本文实例讲述了JS原型和原型链原理与用法。分享给大家供大家参考,具体如下: Javascript语言的继承机制一直很难被人理解。 它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance)的区分,...
  • JavaScript 原型链继承面试题

    千次阅读 2020-10-29 02:00:37
    JavaScript 原型链继承问题 JavaScript 中没有类的概念的,主要通过原型链来实现继承。通常情况下,继承意味着复制操作,然而 JavaScript默认并不会复制对象的属性,相反,JavaScript只是在两个对象之间创建一个...
  • 主要介绍了JavaScript使用原型和原型链实现对象继承的方法,简单讲述了javascript原型原型链原理,并结合实例形式详细分析了javascript中对象继承的常见实现技巧,需要的朋友可以参考下
  • 理解JS原型链到实现继承

    千次阅读 2021-03-22 21:42:06
    理解JS原型链到实现继承 JS是通过原型链的方式能够像一些基于类的语言(如Java、C++)一样实现了类的功能,并且也可以通过原型链进行继承。但是,由于原型链的灵活,在ES5的语法中有许多方式能够实现继承,可能你有...
  • 1.原型链继承 构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。 原型链继承(将父类的实例作为子类的原型): //父类 function Animal...
  • js原型与原型链继承的理解 1. 原型链的概念 ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、...
  • 如果用原型方式重定义前面例子中的类,它们将变为下列形式: 代码如下:function ClassA() {} ClassA.prototype.color = “blue”;ClassA.prototype.sayColor = function () { alert(this.color);}; ...
  • 每个函数都会创建一个prototype对象属性,它就是原型对象,也是我们调用构造函数生成的对象的原型,我们直接打印看下: function Person(name) { this.name = name; } console.dir(Person); 我们看上面的图片...
  • 前面的话 ...原型链继承的本质是重写原型对象,代之是一个新类型的实例. 下列代码中,Fn的新原型不仅有new Fn1()实例上的全部属性和方法,并且还继承了Fn1原型上的属性与方法。 function Fn1() { ...
  • 构造函数、原型、实例三者的关系 构造函数 创建对象的一种常用方式,其他创建对象的方式还包括工厂模式、原型模式、对象字面量等。 每一个构造函数都有一个prototype属性,打印出来之后发现这个属性其实是一个...
  • instanceof:用来判断实例是否是属于某个对象,这个判断依据是什么呢?...实例对象属性查找顺序是:实例对象内部—->构造函数原型链—->实例对象父对象的原型链。 //继承机制 function A(){ } A.prototype.
  • 当初ECMAscript的发明者为了简化这门语言,同时又保持继承的属性,于是就设计了这个链表。。 在数据结构中学过链表不,链表中有一个位置相当于指针,指向下一个结构体。 于是乎__proto__也一样,每当你去定义一个...
  • 原型链继承是比较常见的继承方式之一,其中涉及的构造函数、原型和实例,三者之间存在着一定的关系,即每一个构造函数都有一个原型对象,原型对象又包含一个指向构造函数的指针,而实例则包含一个原型对象的指针。...
  • javascript 原型链继承

    2017-01-08 14:22:50
    javascript 原型链继承
  • JavaScript学习(五十四)—原型链继承的概念以及原理 一、原型链 所谓原型链就是指通过原型链继承,在原型之间建立起来的链式结构被称为原型链。 当查找对象的某个属性时,会先从该对象的私有属性中查找,如果有则...
  • ECMAScript 只支持实现继承,而且其实现继承主要是依靠原型链来实现的。 本节目录一、原型链1.1 构造函数、原型和实例的关系1.2 原型链的基本概念1.3 原型链的原型搜索机制1.4 所有函数的默认原型 -...
  • 原型链继承 ②借用构造函数继承 ③组合继承 接下来让我们逐个的对其进行剖析。 方式一、继承模式-原型链继承 为了更好的理解为什么要这样做,我们来看一看这样做的图示: 代码核心思路: 通过将子类型的原型...
  • 什么是原型语言只有对象,没有类;对象继承对象,而不是类继承类。“原型对象”是核心概念。原型对象是新对象的模板,...root节点的顶层对象是一个语言原生的对象,只有它没有原型对象,其他所有对象都直接或间接继承它...
  • 这种方式叫做构造函数继承,而因为原型可以共享方法,那么也可以使用原型链来实现继承,不仅仅是继承方法,也可以继承原型上的属性,毕竟原型上的方法和属性都能够被相应的实例对象通过原型链继承,所以这种方式被...
  • js原型链污染(超详细)

    2021-08-23 13:49:26
    js创建对象的三种方法 : 普通创建 var person={name:'lihuaiqiu','age','19'} ​ var person={} //创建空对象 构造函数方法创建 function person(){ this.name="liahuqiu"; this.test=function () { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,161
精华内容 6,864
关键字:

js原型链继承原理

友情链接: WindowsMessage.rar