js继承——到继承结束
说到继承,其它语言里可能有两种: 接口继承是继承方法签名,而实现继承则继承实际方法。ES函数没有签名,不能实现接口继承,只支持实现继承,而实现继承主要依靠原型链。(这两句话,说来轻松,理解来不易,且行且珍惜吧~)。
所以,理解原型链是掌握继承的必要条件。一个原型对象等与另一个类型的实例
function Parent(){
this.super = "parent";
this.friends = ["A", "B", "C"];
}
Parent.prototype.getParentValue = function(){
return this.super;
}
function Child(){
this.sub = "Child";
}
Child.prototype = new Parent();
Child.prototype.getChildValue = function(){
return this.sub;
}
var c1= new Child();
c1.getParentValue(); //"parent"
c1.getChildValue(); //"Child"
c1.constructor === Parent; //true
c1.constructor === Child; //false
var c2= new Child();
c2.friends.push("D");
c2.friends //["A", "B", "C", "D"]
c1.friends //["A", "B", "C", "D"]
为什么demo.constructor ===Parent;呢? 因为demo.prototype指向Parent实例,而Parent.prototype.constructor指向Parent,因此demo.constructor继承自 Parent.prototype,所以指向Parent;
使用原型练实现继承:说明:不能用对象字面量创建原型方法,因为这样会重写原型链。
缺点:1.引用类型值的原型属性会被所有实例共享,因此在构造函数中定义属性,但通过原型继承时,一个类型的实例会变成另一个对象的原型。因此实例中的属性就变成了现在的原型的属性了。2.没有办法在不影响所有对象的情况下,向超类型传参。
为了解决引用类型带来的问题——>借用构造函数(伪造对象、经典继承 ):在子类型构造函数的内部调用超类型构造函数
function Parent(){
this.friends = ["A", "B", "C"];
}
function Child(){
Parent.call(this);
this.age = 23;
}
var c1 = new Child();
var c2 = new Child();
c1.friends.push("D");
c1.friends //["A", "B", "C", "D"]
c2.friends //["A", "B", "C"]
c2.age //
借用构造函数的缺点:无法避免构造函数模式的缺点,方法不能复用,而且超类原型中的方法,对于子类型是不可见的,所以只能统一使用构造函数模式。
为了避免这些缺点——>组合继承(伪经典继承):使用原型链实现对原型属性和方法的继承,而通过构造函数实现对实例属性的继承
function Parent(name){
this.name = name || "parent";
this.friends = ["A", "B", "C"];
}
Parent.prototype.sayName = function (){
return this.name;
}
function Child(name, age){
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
var c1 = new Child("Tom", 34);
var c2 = new Child("Joe", 22);
c1.friends.push("D");
c2.friends //["A", "B", "C"]
c1.sayName(); //"Tom"
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点。成为js中最常用的继承模式。
此外还有几种继承模式——>原型式继承:借用原型基于已有的对象创建新的对象,同时还不必因此创建自定义类型。
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var person = {
name: "Tom",
friends: ["A", "B", "C"]
};
var p1= object(person);
p1.name = "Marry";
p1.friends.push("D");
var p2 = object(person);
p2.name = "Joe";
p2.friends.push("E"); person.friends //["A", "B", "C", "D", "E"]
object()函数中创建了一个临时构造函数,并将传入的对象作为该构造函数的原型。相当于进行一次浅复制。和原型模式一样,引用类型始终会被共享。其中ES5定义了Object.create()方法规范了原型继承。
因此,在没必要兴师动众的创建构造函数,而只想让一个对象与另一个对象保持类似的情况下,原型式模式是个不错的选择。
——>寄生式继承:与原型式继承紧密相关的一种思路,与寄生构造函数和工厂模式类似,即创建一个封装继承过程的函数,该函数在内部以某种方式来增强对象。
function createAnother(o){
var clone = object(o);
clone.sayHi = function(){
return "HI";
};
return clone;
}
var person = {
name: "Tom",
friends: ["A", "B", "C"]
};
var p = createAnother(person);
p.sayHi() //"HI"
在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式也是一种有用的模式,object()非必须,任何能返回新对象的函数都适用于此模式
组合模式是最常用的继承模式,但是组合模式两次调用超类型构造函数,
为了解决这个问题——>寄生组合模式:使用构造函数继承属性,通过原型链的混成形式继承方法;不必为了指定子类型的原型而调用超类型的构造函数,我们可以使用寄生式继承继承超类型的原型,然后再将结果指定给子类型的原型。
function inheritPrototype(C, P){
var prototype = object(P.prototype);
prototype.constructor = C;
C.prototype = prototype;
}
function Parent(name){
this.name = name || "parent";
this.friends = ["A", "B", "C"];
}
Parent.prototype.sayName = function (){
return this.name;
}
function Child(name, age){
Parent.call(this, name);
this.age = age;
}
inheritPrototype(Child, Parent);
Child.prototype.sayAge = function(){
return this.age;
};
组合继承模式:集寄生模式和组合模式优点于一身,是实现基于类型继承最有效最理想的方式。
js继承——到继承结束的更多相关文章
- js面向对象之继承那点事儿根本就不是事
继承 说道这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名):一种是实现继承(继承实际的方法) 奈何js中没有签名,因而只有实现继承,而且 ...
- js对象的继承以及公有私有属性的定义和读写
最近想写一些js工具,有些方面需要用到面向对象的方法,比如继承父类属性和方法.通过私有化隐藏某些对象的属性等,因为没有系统的学习js,所以不知道怎么做,觉得很伤脑筋. 今天受到技术群里朋友的提示,并查 ...
- 浅谈JS中的继承
前言 JS 是没有继承的,不过可以曲线救国,利用构造函数.原型等方法实现继承的功能. var o=new Object(); 其实用构造函数实例化一个对象,就是继承,这里可以使用Object中的所有属 ...
- web前端开发必懂之一:JS继承和继承基础总结
首先,推荐一篇博客豪情的博客JS提高: http://www.cnblogs.com/jikey/p/3604459.html ,里面的链接全是精华, 一般人我不告诉他; 我们会先从JS的基本的设计模 ...
- js如何实现继承
js继承有5种实现方式:1.继承第一种方式:对象冒充 function Parent(username){ this.username = username; this.hello = ...
- JS创建对象、继承原型、ES6中class继承
面向对象编程:java中对象的两个基本概念:1.类:类是对象的模板,比如说Leader 这个是泛称领导,并不特指谁.2:实例:实例是根据类创建的对象,根据类Leader可以创建出很多实例:liyi,y ...
- js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。
js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法. function ClassA(sColor) { this.color = sColor; } Class ...
- js模拟实现继承功能
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- js原生设计模式——2面向对象编程之继承—原型继承(类式继承的封装)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
随机推荐
- LINUX gcc安装rpm包顺序
rpm -ivh cpp-4.1.2-42.el5.i386.rpm rpm -ihv kernel-headers-2.6.18-92.el5.i386.rpm rpm -ivh glibc-hea ...
- java并发编程实战笔记---(第四章)对象的组合
4.1设计线程安全的类 包含三个基本要素: 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 2.简历对象状态的并发访问管理策略 对象的状态: 域 基本类型所有域, 引用类型包括被引用 ...
- DB2和Oracle中Date比较
- 洛谷P1482 Cantor表(升级版) 题解
题目传送门 此题zha一看非常简单. 再一看特别简单. 最后瞟一眼,还是很简单. 所以在此就唠一下GCD大法吧: int gcd(int x,int y){ if(x<y) return gcd ...
- Hadoop(六)MapReduce的入门与运行原理
一 MapReduce入门 1.1 MapReduce定义 Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于hadoop的数据分析应用”的核心框架: Mapreduce核心功能是将用 ...
- day1 作业编写登录窗口
作业一:编写登录接口 (1)输入用户名和密码: (2)认证成功后显示欢迎信息: (3)输错三次后锁定. 思路:我们知道,要想让程序记住之前输入多少次,锁定用户,那么可以使用数据库来保存用户的状态,然而 ...
- Yii 简明学习教程
Yii是一个基于组件的高性能PHP框架,用于快速开发Web应用程序(下面内容基于Yii 1.1) 1. 典型的工作流 用户向入口脚本index.php发起请求 入口脚本加载应用配置config.php ...
- 使用 JQuery 实现将 table 按照列排序
使用 JQuery 实现将 table 按照列排序 使用 JQuery 实现将 table 按照列排序 代码如下 <!DOCTYPE html> <html> <head ...
- ThinkPHP 多语言的实现
1.按照官方文档进行修改 2.注意区分项目语言包和系统语言包 3.实现语言包和数据库语言同步切换 4.thinkPHP多语言实现与Cookie有关, 谷歌浏览器下按F12查看Request Heade ...
- phpstorm配置关联php手册
最近发现有些编辑器可以 选中函数名,通过相应的快捷键就可以调用 浏览器 打开相应 函数的 在线帮助文档. 一番查找,我终于发现 phpStorm 也有相应的功能. 一.自带功能 在编辑器中选中函数名, ...