js继承的实现(原型/链、函数伪装)

一、原型继承父类的实例

        //父类及其原型属性/方法
        function SuperType () {
            this.name = [‘zc‘,‘ls‘,‘ww‘];
        }
        SuperType.prototype.getSuperName = function() {
            return this.name;
        };

        //子类及其原型属性/方法
        function SubType() {
            this.test = [‘a‘,‘b‘,‘c‘,‘d‘];
        }
        //子类型的原型指向父类型的实例(即子类的原型复制了父类的构造器以及父类原型属性/方法)
        SubType.prototype = new SuperType();
        //为子类原型添加原型拓展属性/方法
        SubType.prototype.getSubTest = function() {
            return this.test;
        }

        var instance1 = new SubType();
        instance1.name.push(‘yzy‘);//name属性是原型继承自父类实例
        instance1.test.push(‘e‘);//test属性是源于子类本身的构造器
        console.log(instance1.name,instance1.test)

        var instance2 = new SubType();
        console.log(instance2.name,instance2.test)

控制台输出:

标注:

注意这里的子类原型指向一个父类的实例(引用传递),那么这块的父类实例就是内存中的一块地址,以后所有的子类实例都会有一个原型属性指向这块地址,并且子类A对这块地址中数据更改也会影响到子类B。

图示:

所以你可以看到,instance1.name是从父类实例来的,这个属性实际存在于这个单例,访问的时候都是引用传递,由于这个单例是共享的,instance1 push了一个数据,那么就算instance2没有任何动作,instance2读的时候数据也会是变化后的数据;

而对于test属性,是子类自身的,所以这个属性值存在于子类实例自身,相互之间互不影响,所以虽然instance1.test push了一个数据,但是instance2访问的时候丝毫不受影响。

缺点:继承自父类实例的原型属性会被所有实例所共享

二、构造函数伪装(call()、apply())

        //父类及其原型属性/方法
        function SuperType(name) {
            this.name = name;
            this.color = [‘green‘,‘red‘];
        }
        SuperType.prototype.getSuperName = function() {
            return this.name;
        }

        //子类及其原型属性/方法
        function SubType(name) {
            SuperType.call(this, name);this.test = [‘a‘,‘b‘,‘c‘,‘d‘];
        }
        SubType.prototype.getSubTest = function() {
            return this.test;
        }

        var instance1 = new SubType(‘Jack‘);
        console.log(instance1.name,instance1.getSubTest());
        console.log(‘------------------------‘);
        console.log(instance1.getSuperName())

控制台输出:

标注:

call()方法实际上就是在当前作用域拷贝了一下函数执行者的构造函数/方法,所以上述call()方法实际上做了如下的事情

        //子类及其原型属性/方法
        function SubType(name) {
            //SuperType.call(this, name);
            this.name = name;
            this.color = [‘green‘,‘red‘];

            this.test = [‘a‘,‘b‘,‘c‘,‘d‘];
        }

注意的是,call()函数伪装并不会在当前作用域执行 SuperType 原型下的方法/属性

所以,因为 getSuperName() 是父类原型下的方法,所以call() 方法自然不会复制该方法给 SubType 构造器,因此控制台报错也就是理所当然的咯

缺点:函数伪装不会继承父类的原型属性/方法虽然子类实例不会

原文地址:https://www.cnblogs.com/eco-just/p/11106079.html

时间: 2024-11-02 05:32:11

js继承的实现(原型/链、函数伪装)的相关文章

282 继承模式:原型链继承 : 得到方法,借用构造函数 : 得到属性,组合,new一个对象背后做了些什么

1.原型链继承 : 得到方法 function Parent(){} Parent.prototype.test = function(){}; function Child(){} Child.prototype = new Parent(); // 子类型的原型指向父类型实例 Child.prototype.constructor = Child var child = new Child(); //有test() <!DOCTYPE html> <html lang="e

原型、函数伪装(apply,call)、继承

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>原型与继承</title>     <script type="text/javascript">         /*          * 组合的方式是属性通过伪造的方式实现,方法通过原型链的方式实现,注意

第20篇 js高级知识---深入原型链

前面把js作用域和词法分析都说了下,今天把原型链说下,写这个文章费了点时间,因为这个东西有点抽象,想用语言表达出来不是很容易,我想写的文章不是简单的是官方的API的copy,而是对自己的知识探索和总结的过程,以及在这个过程碰到的问题都一一写出来,我想大多数人应该也有这个疑惑,然后带着疑惑去找答案,当你把这个疑惑解决之后,才觉得很有成就感.下面不多说了,开始说说什么是原型链.要想了解原型链,还是要从简单的开始,什么是原型?首先看下代码: function funcA() { this.show =

关于JS面向对象中原型和原型链以及他们之间的关系及this的详解

一:原型和原型对象: 1.函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址. 2.函数的原型对象__proto__:所有对象都有__proto__属性, 当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性指向 构造函数的prototype. 1 zhangsan.__proto__==Person.prototype 注:在上述代码中Person是构造函数,zhangsan则是该构造函数的一个实例化对象.

JavaScript-原型&amp;原型链&amp;原型继承&amp;组合函数

小小的芝麻之旅: 今天学习了js的原型,要说原型,我们先简单说一下函数创建过程. 原型 每个函数在创建的时候js都自动添加了prototype属性,这就是函数的原型,原型就是函数的一个属性,类似一个指针.原型在函数的创建过程中由js编译器自动添加. <script type="text/javascript"> function Flower(name,area) { this.name=name; this.area=area; this.showName=myName;

JS原型链与几种继承方法的对比

继承的方式有两种:接口继承.实现继承接口继承:即虚函数,父类只定义接口,不具体实现子类继承接口,自己负责实现这个方法,运行时动态决定调用哪个实现.实现继承:父类实现的方法,子类可以直接调用 JS中只支持实现继承,以原型链来实现. 回顾一下构造函数.原型.实例的关系:每个构造函数都有一个原型对象,原型对象又都包含一个constructor指针指向构造函数,实例包含一个_proto_内部属性指向原型对象. 继承的实现方法(父类型叫Parent,子类型叫Child)原本Child.prototype

深入理解JS继承和原型链

对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念( ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型). 涉及到继承这一块,Javascript 只有一种结构,那就是:对象.在 javaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接.这个原型对象又有自己的原型,直到某个对象的原型为null 为止

js继承与原型链

对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念(虽然 class 是个保留字,不能作为变量名来使用). 继承方面,JavaScript 中的每个对象都有一个内部私有的链接指向另一个对象,这个对象就是原对象的原型.这个原型对象也有自己的原型,直到对象的原型为 null 为止(也就是没有原型).这种一级一级的链结构就称为原型链. 虽然这通常会被称作 JavaScrip

js(4) 继承与原型链

一:使用原型链来实现继承 在介绍原型链之前,要引入构造函数,原型,和实例的关系 构造函数都有一个原型对象,在原型对象中存在一个指向构造函数的指针(constructor),在实例中包含一个指向原型对象的内部指针(prototype) 构建原型链的原理是让一个类型的原型对象等于另一个类型的实例 当使用new 操作符构造实例的时候,实例会拥有构造函数原型中的属性和方法 实现代码如下: function SuperType(){ this.property=true; }//在SuperType的原型

JS原型+原型链+设计模式

JavaScript是一种基于对象的语言,JavaScript中的所有对象,都具有prototype属性.prototype属性返回对象的所有属性和方法,所有 JavaScript 内部对象都有只读的 prototype 属性,可以向其原型中动态添加属性和方法,但该对象不能被赋予不同的原型.但是自定义的对象可以被赋给新的原型. 对象分为函数对象和普通对象,区分:凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象.(Object ,Function 是JS自带的函数