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继承有几种继承方式,现在来说说其中的组合继承。

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

 

原文地址:https://www.cnblogs.com/shiwz/p/7070576.html