zoukankan      html  css  js  c++  java
  • JavaScript-原型&原型链&原型继承&组合函数

    原型

    每个函数在创建的时候js都自动添加了prototype属性,这就是函数的原型,原型就是函数的一个属性,类似一个指针。原型在函数的创建过程中由js编译器自动添加。

    <script type="text/javascript">
            function Flower(name,area) {
                this.name=name;
                this.area=area;
                this.showName=myName;
            }
            //全局对象,浏览器 解析器 代码
            function myName() {
                alert(this.name);
            };
            //创建出一个flower对象
            var f1=new Flower("好天气","待机时间苦咖啡");
             f1.showName();
            var f2=new Flower("接信息","你的那份你看到");
            f2.showName();
            if(f1.showName==f2.showName){
                 alert("==");
            }else{
                alert("!=");
            }
        <
    /script>

    原型链

    在JavaScript中,每个对象都有一个[[Prototype]]属性,其保存着的地址就构成了对象的原型链
    [[Prototype]]属性是js编译器在对象被创建时自动添加的,其取值由new运算符的右侧参数决定。字面量的方式可转化为new Obejct();

    var x =new Flower();
    vae o = {};  //var o = new Obejct();

    通过对象的[[Prototype]]保存对另一个对象的引用,通过这个引用往上进行属性的查找,这就是原型链查找机制

    对象在查找某个属性的时候,会首先遍历自身的属性,如果没有则会继续查找[[Prototype]]引用的对象,如果再没有则继续查找[[Prototype]].[[Prototype]]引用的对象,依次类推,直到[[Prototype]].….[[Prototype]]undefined

    prototype本身是一个Object对象的实例,所以其原型链指向的是Object的原型。

    <script type="text/javascript">
    
            function HUmens(){
                this.foot=2;
            }
    //写一个关于Humens的一个原型上的方法,获取到foot
            HUmens.prototype.getFoot=function () {
                return this.foot;
            };
            //写一个子类Man
            function Man() {
                this.head=1;
            }
             Man.prototype=new HUmens();
            Man.prototype,getHead=function () {
                return this.head;
            };
            var man1=new Man();
            alert(man1.foot);
    
        </script>

    基于原型链的继承

    继承属性

    JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

    prototype 和 Object.getPrototypeOf

    对于从 Java 或 C++ 转过来的开发人员来说 JavaScript 会有点让人困惑,因为它全部都是动态的,都是运行时,而且不存在类(classes)。所有的都是实例(对象)。即使我们模拟出的 “类(classes)”,也只是一个函数对象。

    你可能已经注意到,我们的函数 A 有一个特殊的属性叫做原型。这个特殊的属性与 JavaScript 的 new 运算符一起工作。对原型对象的引用会复制到新实例内部的 __proto__ 属性。例如,当你这样: var a1 = new A(), JavaScript 就会设置:a1.__proto__ = A.prototype(在内存中创建对象后,并在运行 this 绑定的函数 A()之前)。然后在你访问实例的属性时,JavaScript 首先检查它们是否直接存在于该对象中(即是否是该对象的自身属性),如果不是,它会在 __proto__ 中查找。也就是说,你在原型中定义的元素将被所有实例共享,甚至可以在稍后对原型进行修改,这种变更将影响到所有现存实例。

    像上面的例子中,如果你执行 var a1 = new A(); var a2 = new A(); 那么 a1.doSomething 事实上会指向Object.getPrototypeOf(a1).doSomething,它就是你在 A.prototype.doSomething 中定义的内容。比如:Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething。

    简而言之, prototype 是用于类型的,而 Object.getPrototypeOf() 是用于实例的(instances),两者功能一致。

    __proto__ 看起来就像递归引用, 如a1.doSomething,Object.getPrototypeOf(a1).doSomething,Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething 等等等, 直到它找到 doSomething 这个属性或者 Object.getPrototypeOf 返回 null。

    关于javascript中apply()和call()方法的区别

    如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript,先理解JavaScrtipt动态变换运行时上下文特性,这种特性主要就体现在applycall两个方法的运用上.

    区分apply,call就一句话,

    foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments)==this.foo(arg1, arg2, arg3)

     call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性.既然作为方法的属性,那它们的使用就当然是针对方法的了.这两个方法是容易混淆的,因为它们的作用一样,只是使用方式不同.

    相同点:两个方法产生的作用是完全一样的

    不同点:方法传递的参数不同

     javascript继承有几种继承方式,现在来说说其中的组合继承。

        组合继承是结合了原型借用构造函数这两种技术的继承方式,分别利用它们的长处,避免了短处。

     

  • 相关阅读:
    CLR的黑暗面——栈与引用对象
    delegate的另类玩法
    一个比较bt的xslt
    关于string
    jQuery核心讲解
    Linux环境进程间通信(二):信号(上)
    ubuntu10.10 轻松安装 Nvidia 官方驱动
    Linux环境进程间通信(二): 信号(下)
    Linux 信号signal处理机制
    java.lang.ProcessBuilder类和java.lang.Process类
  • 原文地址:https://www.cnblogs.com/shiwz/p/7070576.html
Copyright © 2011-2022 走看看