精华内容
下载资源
问答
  • javascript 原型链继承

    2017-01-08 14:22:50
    javascript 原型链继承

    JavaScript中没有类的概念,只有一个构造函数来创建对象。

    但是JavaScript也可以实现继承。

    首先要说的是,JavaScript中的对象分为函数对象和普通对象。

    何为函数对象??

    就是 这样的对象  

    function f()

    {

    }

    除了函数对象,其他的对象皆为普通对象。

    接下来我们来说一说,构造函数、实例、原型对象之间的关系。

    函数对象内部有一个prototype属性用于引用到该对象的原型对象。其实原型对象也是很普通的。

    相当于隐式的写了这样的代码

    var fPrototype = new f();

    f.prototype = fPrototype;

    原型对象和一般的实例没有太多区别。

    一般由构造函数产生的实例内部有这样的一个属性 --->    __proto__这个属性引用了自己的原型对象。

    用一张图片来说明三者的关系吧


    接下来我们在看一断代码。



    这里,笔者明明没有在构造函数中定义username属性 但是结果却取到了值。

    这里呢,是这样的,现在当前的对象里面找,看其是否有当前属性名,如果没有则到原型对象里面去找该属性。一直顺着原型链找到Object.prototype.

    找不到则为undefined。

    应用这个原理我们可以实现JavaScript的继承。

    我们可以大致划一下这个继承过程的图。



    所以说,实现原型链继承的关键是__proto__而不是  函数对象里的prototype属性

    上原型继承的代码demo

    function Parent(username)
    {
        this.username = "aaa";
    }
    Parent.prototype.sayHello = function()
    {
        console.log(this.username);
    };
    
    Parent.prototype.aaa = function()
    {
        console.log("helloworld");
    };
    function Child(username, password)
    {
        // Parent.call(this, username);
        this.password = password;
    }
    
    Child.prototype.sayWorld = function()
    {
        console.log(this.password);
    };
    
    
    Child.prototype = new Parent();
    
    var child = new Child("zhangsan", "123");
    child.sayHello();
    console.log( child.__proto__.__proto__.__proto__.__proto__);

    如有讲的不对的地方,欢迎斧正,希望对各位读者有帮助.
    展开全文
  • 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:在原型对象上定义属性和方法,其所有的构造函数实例都能共享原型上的属性和方法,因此如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象。

    展开全文
  • 主要介绍了javascript原型链继承用法,实例分析了javascript原型链继承中的技巧与相关注意事项,非常具有实用价值,需要的朋友可以参考下
  • javascript原型链继承

    2015-07-05 14:09:52
    javascript原型链继承 一、关于javascript原型的基本概念: prototype属性:每个函数都一个prototype属性,这个属性指向函数的原型对象。原型对象主要用于共享实例中所包含的的属性和方法。 ...

    javascript原型链继承

    一、关于javascript原型的基本概念:

    prototype属性:每个函数都一个prototype属性,这个属性指向函数的原型对象。原型对象主要用于共享实例中所包含的的属性和方法。

    constructor属性:每个原型对象都有一个constructor属性,这个constructor属性包含一个指向prototype属性所在函数的指针。 例如 Foo.prototype.constructor指向Foo函数。这个属性是只读的。

    __proto__属性(ES6通过对__proto__属性进行标准化):创建一个构造函数的实例后,这个实例包含一个指针,指向这个构造函数的原型对象,这个指针叫做[[Prototype]],在chrome、Safari、Firefox下可通过对象的__proto__属性访问。__proto__属性是实例才拥有的,在javascript中函数也是对象,它是Function类型的实例, 所以函数也有__proto__属性。

    我们来看这样一个关系图:

        (图片来自:http://www.mollypages.org/misc/js.mp)

     

      通过这个关系图,我们可以得到以下信息:

    • 实例的__proto__属性始终指向它构造函数的原型对象:
    1 function Foo(){};
    2 var foo=new Foo();
    3 console.log(foo.__proto__===Foo.prototype); //true
    4 console.log(Foo.__proto__===Foo.constructor.prototype);//ture

     

    • 所有对象最终都会指向Object对象:
    1 function Foo(){};
    2 var foo=new Foo();
    3 console.log(foo.__proto__); //输出Foo{},表示指向Foo构造函数的原型
    4 console.log(foo.__proto__.__proto__); //输出Object{},表示指向Object构造函数的原型
    5 console.log(foo.__proto__.__proto__.__proto__); //null
    • 用户自定义函数的__proto__属性指向Function.prototype,所以它们都是Function构造函数的实例。

    二、开始说原型链继承:

      现在,有了前面基本概念的了解,我再说关于原型链的继承,首先来看以下代码:

    复制代码
     1 function Foo(name){
     2     this.name=name;
     3 }
     4 Foo.prototype.myName=function(){
     5         console.log("my name is "+this.name);
     6 }
     7 
     8 function Bar(name){
     9      this.name=name;
    10 }
    11 Bar.prototype=new Foo(); //Bar的原型指向Foo的实例
    12 var bar=new Bar("Dog");
    13 bar.myName();//输出:”my name is Dog“
    复制代码

      以上代码实现了Bar构造函数继承了Foo构造函数的myName()方法。继承是通过原型链的查找来实现的,原型链的查找规则是:当实例调用一个属性(或方法)时,首先会在这个实例中查找该属性(或方法),在没有找到的情况下,会继续在这个实例的原型上查找,如果依旧找不到这个属性(或方法),搜索过程会沿着原型链向上查找,直到原型链的末端,整个查找过程才会停止。上面例子的原型链关系如图:

     

         例子中当实例bar调用myName()方法时,会首先在bar这个实例中查找有没有myName()这个方法,如果没有找到,则会在Bar.prototype上查找,在Bar.prototype上没有找到的情况下,继续在Foo.prototype上查找,结果在Foo.prototype上找到了该方法。

       为什通过 “Bar.prototype=new Foo()” 能够实现这样有继承关系的原型链呢?我们可以通过以下代码来验证:

    复制代码
     1 function Foo(name){
     2     this.name=name;
     3 }
     4 Foo.prototype.myName=function(){
     5         console.log("my name is "+this.name);
     6 }
     7 
     8 function Bar(name){
     9      this.name=name;
    10 }
    11 
    12 var foo=new Foo();
    13 Bar.prototype=foo;
    14 var bar=new Bar();
    15 bar.__proto__===Bar.prototype;  //返回true
    16 bar.__proto__===foo; //返回true
    17 bar.__proto__.__proto__===foo.__proto__; //返回true
    18 foo.__proto__===Foo.prototype; //返回true,证明了Bar 继承了Foo
    复制代码

       或许你会问通过“Bar.prototype=new Foo()”能够实现继承,为什么不是“Bar.prototype=Foo.prototype”呢?好的,下面先看这段简单的代码:  

    1 a={a:1,b:2};
    2 b=a;
    3 b.c=3;
    4 console.log(a.c); //3 ,a和b是引用类型

      看完这段代码,我们想象一下,Bar.prototype  和Foo.prototype也是Object类型的,所以它们之间相互赋值,将指向相同数据地址,若修改Bar原型上的属性,Foo原型上的同名属性也会被修改,来看看下面的示例:

    复制代码
     1 function Foo(){}
     2 Foo.prototype.name="Dog";
     3 Foo.prototype.sayName=function(){
     4  console.log("My name is " +this.name);
     5 }
     6 var foo=new Foo();
     7 foo.sayName();//"My name is Dog"
     8 function Bar(){}
     9 
    10 Bar.prototype=Foo.prototype;
    11 Bar.prototype.name="Cat";
    12 var bar=new Bar();
    13 bar.sayName();//"My name is Cat",也能Foo原型上的方法
    14 foo.sayName();//"My name is Cat",Foo原型上的name属性已经被修改
    复制代码

      通过上面的示例我们可以看到,当“Bar.prototype=Foo.prototype”时,如果给Bar.prototype上添加一个name属性,Foo.prototype上name属性也将随之被修改,我们知道继承的目的就是子函数(子类)复用、重写、扩展父函数(父类)的方法,但继承决不允许改变父函数(父类)的方法和属性 ,所以Bar.prototype=Foo.prototype是不能实现继承的。
      那么让“Bar.prototype=Foo”能不能实现继承呢?我们来用代码验证一下:

    复制代码
    1 function Foo(){}
    2 function Bar(){}
    3 Bar.prototype=Foo;
    4 var bar=new Bar();
    5 bar.__proto__===Bar.prototype; //true
    6 bar.__proto__===Foo; //true
    7 Foo.__proto__===Function.prototype; //ture
    8 Function.prototype.__proto__===Object.prototype; //ture
    9 Object.prototype.__proto__===null; //ture
    复制代码

      通过bar.__proto__向上查找不到Foo.prototype,所以Bar构造函数是不能继承Foo构造函数的。

     

    参考资料:《javascript高级程序设计》

                    《JavaScript 继承代码中,B.prototype = new A(); 的含义是什么?》 

    展开全文
  • JavaScript原型链继承

    2019-03-11 23:54:53
    当我们要通过原型链继承时 子类可以调用父类在原型链上的方法 但是子类的构造函数却指向父类 正如下图(其中subClass为实例化过的对象) 这时候可能会想,那我把子类的构造函数指向自身不就好了吗,于是添加...

    首先创建一个父类

    创建一个子类

     

    当我们要通过原型链继承时

    子类可以调用父类在原型链上的方法

    但是子类的构造函数却指向父类

    正如下图(其中subClass为实例化过的对象)

    这时候可能会想,那我把子类的构造函数指向自身不就好了吗,于是添加下面代码

    子类构造函数真的指向了自身,但是我们检查一下父类

    父类的构造函数却指向了子类,如下图所示(其中subClass为实例化过的对象)

    以下是我的解决方法,通过复制一份父类的原型副本保存在变量中,并修改构造函数

    子类继承了父类,但却不影响构造函数,如下图所示(其中subClass为实例化过的对象)

     

    展开全文
  • js原型链继承

    2016-12-16 17:30:28
    在传统的基于Class的语言如Java、C++中,...但是,JavaScript由于采用原型继承,我们无法直接扩展一个Class,因为根本不存在Class这种类型。 但是办法还是有的。我们先回顾Student构造函数: function Student(props)
  • js 原型链继承

    2019-07-04 16:43:47
    构造函数的prototype的__proto__默认指向Object.prototype,是继承Object。 function Animal(age){ this.age = age } Animal.prototype.getAge = function(){ return this.age + ", getAge, prototype" } Animal...
  • Js原型链继承

    2018-05-18 11:29:34
    原型复制 借助空函数 new操作function Child(props) { Parent.call(this, props); this.grade = props.grade || 1; } function inherits(Child, Parent) { var F = function () {}; F.prototype ...
  • 结合阅读: JS原型与原型链终极详解...js原型链继承的是_proto_,而不是prototype。 构造器的实例对象的_proto_指向构造器的原型prototype。 所有构造器都来自Function.prototype,甚至包括根构造器Object及Funct...
  • 本篇文章给大家详细介绍一下JavaScript原型链继承的概念以及原理。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 一、原型链 所谓原型链就是指通过原型链继承,在原型之间建立起来的链式...
  • js原型与原型链继承的理解 1. 原型链的概念 ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、...
  • js中,可通过构造函数的形式来创建对象,并使用各种方式实现继承,其中原型链继承便是一种普遍的方法 什么是原型链继承 先来看一个例子 function Parent () { this.type = 'obj' } function Child () { this...
  • 继承是几乎所有编程语言中都...ES5原型链继承 function Parent(name,age){ this.name=name; this.age=age; } Parent.prototype.be=function(){ console.log('我是原型上的方法'); } function Children(name,age,he
  • 本文总结了ES3,ES5,ES7和NS(NonStandard)四种原型链继承的实现方法。 ECMAScript 6 class将给开发者带来了JavaScript OOP的规范实现,但这中方式的直接应用和普及至少得等到IE11被淘汰掉,而到那时,说不定我已...
  • 利用原型链来实现继承,基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法。 代码如下:  function superClass (){  this.property1 = true;  }   superClass.prototype.method1 =...
  • 浅谈JavaScript原型链继承方式与闭包

    千次阅读 2016-03-19 11:33:03
    JavaScript中的继承方式有两种,一种是通过call或apply方法借用构造函数,另一种方法则是通过原型继承。 这篇文章用于梳理自己关于prototype继承的知识点,也略微涉及一点点闭包的概念。
  • js原型链继承及调用父类方法

    千次阅读 2016-08-05 11:23:05
    function Rect(config){} Rect.prototype.area = function(){ alert("我是父方法"); } function myRect(config){ arguments.callee.prototype.constructor.prototype.area(); //子类里调用父方法area ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,202
精华内容 20,480
关键字:

js原型链继承