zoukankan      html  css  js  c++  java
  • javascript原型继承的学习研究

    几句废话先
    本人目前有.NET平台转向js,但是对js深层次的东西理解的不是很透彻,自己也花了些时间研究js相关技术,今天这篇博文就当是自己学习研究的一个记录吧 :)

    js的原型链prototype
    我一直很难理解js中德继承机制,他不像C#或者java中的那样去实现,而且在js中也没有instance这个概念,也就是说在js中没有`子类`和`父类`的概念,他全靠prototype的模式实现继承机制。关于js的原型继承呢,你也会经常看到这样一句话:
    当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止;

    他的基本查找就是如同下面这段代码所演示的,但是他的内部机制不是这么的简单:

     1 function getProperty(obj, prop) {
     2 if (obj.hasOwnProperty(prop))
     3 return obj[prop]
     4 
     5 else if (obj.__proto__ !== null)
     6 return getProperty(obj.__proto__, prop)
     7 
     8 else
     9 return undefined
    10 }

    说到这,就不得不说一下__proto__,在js中是靠他表示一个对象的原型链,但是使用他是不符合规范的,你将在下面的文章中看到,为什么不能使用他。我们先来举一个例子:

    var say = {
    you:'',
    me:'',
    print:function(){console.log(this.you,this.me)} 
    }
    var p = {you:'jeff',me:'David','__proto__':say}
    p.print();
    

      


    在这里他的__proto__属性指向了say。(在这里我们可以吧这个属性当做一个指针,尽管不是:))


    javascript中让人摸不着头脑的原型继承


    首先咱来谈谈 new关键字:
    造物者:Brendan Eich在设计javascript之初一定受到了c++和java的影响,c++和java还有c#之类的语言在调用new时一定会调用它们的构造函数constructor,但是呢,在javascript中new后面跟的不是类,而是构造函数constructor
    但是呢,这里有一个问题,使用构造函数生成的对象,无法共享其属性和方法,换句话说就是,你是你的,我是我的。
    举一个例子吧:

    1 function say(word){
    2 this.work = work;
    3 this.host = 'David zhang';
    4 }
    5 var sayer1 = new say('今儿北京雾霾太严重了');
    6 var sayer2 = new say('下午6点回家');
    7 //在这里这两个对象的host属性是独立的,
    8 sayer2.host = 'jeff';
    9 alert(sayer1.host); //David Zhang;


    从上面我们可以看出,每个实例对象有自己的属性和方法,实例与实例之间无法共享。这也就导致了资源的浪费

    new的机制: 

    new 运算符接受一个函数 F 及其参数:new F(arguments...)。这一过程分为三步:
    创建类的实例。这步是把一个空的对象的 __proto__ 属性设置为 F.prototype 。
    初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。
    返回实例。


     javascript中真正的原型继承
    说到这咱又要说到咱的大宗师:`道格拉斯`了是他发现了一种可以利用 new 来实现真正的原型继承的方式:

    1 Object.create = function (parent) {
    2 function F() {}
    3 F.prototype = parent;
    4 return new F();
    5 };

    上面那个say对象现在可以写成:

    1 var say = {
    2 you:'',
    3 me:'',
    4 print:function(){console.log(this.you,this.me)} 
    5 };
    6 var s = Object.create(say);
    7 s.you = 'noder';
    8 s.me = 'David Zhang';
    9 s.print(); //noder David Zhang


    但是呢,Object.create()的性能比new差的很多!
    现在说说为什么不要用`__proto__`:因为这样会对父类的所有子类开放整个原型链的操作权限(太可怕了!)

    1 var s = new function(){}
    2 P.prototype.name = 'David'
    3 var a = new s()
    4 a.name // 'David'
    5 a.__proto__ === s.prototype //true
    6 a.__proto__.name = 'Zhang'
    7 P.prototype.name // 被修改为'Zhang'


    重点回顾
    javascript中德原型链继承了啥:
    说到底就是继承了构造函数和原型链两个东西,构造函数继承就是意味着,把父类的属性方法给copy一边,对其进行修改也不会影响到其他的实例。
    而对于原型链的继承就表示子类和超类公用原型链上的东西,修改的话,只能从超类修改

    几点要说:

    本人也在学习之中,上述述说中如有错的地方,请雅正。
    本博文允许转载,但请标明来源

  • 相关阅读:
    mysql-sql中变量的使用
    group by 几种不同情况下的聚合运算
    idea中git撤回commit内容
    mysql按照指定的顺序排序(order by case when)
    根据字段的不同值进行升序和降序排序
    索引
    idea 新建git分支并提交
    idea 编辑区浏览器图标
    idea 首字母小写的时候没有相关提示
    Excel—分组然后取每组中对应时间列值最大的或者最小的
  • 原文地址:https://www.cnblogs.com/struCoder/p/3827027.html
Copyright © 2011-2022 走看看