前前后后已经快写了2年左右javaScript,刚开始只是简单用于一些表单验证和操作dom节点,并没有深入的使用,随着渐渐的深入,开始不想去写重复的代码(懒的开始),从而写简单的继承,封装,抽象等等,最终效果写重复代码少、可用性高(主要:迭代快、代码可以持续使用,加班也少)

Demo构造函数声明类

function Person(name){
this.name = name;
}
new生成实例

new生成实例的缺点:无法共享属性和方法,每次new新的实例会开辟新的内存空间,造成极大的资源浪费。

var personA = new Person('小明');
console.log(personA.name);

构造函数的this指向新的实例

如:

function Person(name){
this.name = name;
this.sex = '女'
} var personA = new Person('小明');
var personB = new Person('小妞');
personA.sex = '男';
console.log(personB.sex); //女

在这里我们该采用声明解决方案呢?设计者很好的解决了这个问题,那么就是prototype属性(包含对象)的引入

prototype属性

它的好处是,实例一旦创建,将自动共同持有共享属性和方法,如:

function Person(name){
this.name = name;
}
Person.prototype.sex = '女';
var personA = new Person('小明');
var personB = new Person('小妞');
console.log(personA.sex); //女
console.log(personB.sex); //女 //证明它们是共享的
Person.prototype.sex = '男';
console.log(personA.sex); //男
console.log(personB.sex); //男

也许在这里你看不出prototype的好处,但是当你有很多方法和属性时,你的运行效率还高嘛?那么:

function Person(name, sex){
this.name = name;
this.sex = sex,
this.country = '中国',
this.show = function(){
console.log(this.name + '的国籍是:'+this.country+',性别:'+this.sex);
}
}
var personA = new Person('小明'.'男');
personA.show(); //小明的国籍是是中国,性别:男
var personB = new Person('小妞','女');
personB.show(); //小妞的国籍是是中国,性别:女

感觉似乎没有什么问题,但是personA和personB都包含有country、show属性方法一模一样的内容,这样就造成了空间的浪费,效率也降低了,那么我们可以它们共享属性和方法

function Person(name, sex){
this.name = name;
this.sex = sex,
} Person.prototype.country = '中国';
Person.prototype.show = function(){
console.log(this.name + '的国籍是:'+this.country+',性别:'+this.sex);
} var personA = new Person('小明'.'男');
var personB = new Person('小妞','女');
personA.show(); //小明的国籍是是中国,性别:男
personB.show(); //小妞的国籍是是中国,性别:女

配合protorype使用的属性--isPrototypeOf(),hasOwnPrototype(),in

function Person(name, sex){
this.name = name;
this.sex = sex,
} Person.prototype.country = '中国';
Person.prototype.show = function(){
console.log(this.name + '的国籍是:'+this.country+',性别:'+this.sex);
} //isPrototypeOf() 判断实例和对象之间的关系
console.log(Person.prototype.isPrototype(personA)) //true
console.log(Person.prototype.isPrototype(personB)) //true //hasOwnPrototype() 判断属性是本地属性,还是继承自prototype属性
console.log(personA.hasOwnPrototy('name')) //true
console.log(personA.hasOwnPrototy('country')) //false //in 判断是否含有属性,不管本地还是继承prototype
console.log('name' in personA) //true
console.log('country' in personA) //true

constructor属性

继续使用前面Person原型对象

function Person(name){
this.name = name;
}
Person.prototype.sex = '女';
var personA = new Person('小明');
var personB = new Person('小妞');
//新增的实例自动包含有constructor属性
console.log(personA.constructor == Person); //true
console.log(personB.constructor == Person); //true

这里也可以使用instanceof判断实例和原型对象之间的关系

console.log(personA instanceof Person);  //true
console.log(personB instanceof Person); //true

常用Object之间“继承”(构造函数继承)(5种)

假设现在有Person和Teacher两个Object,想让Teacher继承Person

//Person对象
function Person(name){
this.name = name;
} //Teacher对象
function Teacher(age,sex){
this.age = age;
this.sex = sex;
}
1、利用构造函数绑定(call或者apply)
function Teacher(age,sex,name){
Person.apply(this,name);//Person.call(this,name);
this.age = age;
this.sex =sex;
}
2、使用prototype,也就是我们前面说prototype属性,修改constructor指向
Teacher.prototype = new Person('xiaoming'); //修改prototy对象原先的值
Teacher.prototype.constructor = Teacher;
var teacher1 = new Teacher(19,'女');
3、直接继承prototype
function Person(){}
person.prototype.name = "xiaoming"; function Teacher(age,sex){
this.age = age;
this.sex = sex;
} //Teacher的prototype对象直接指向Person的prototype对象
Teacher.prototype = Person.prototype;
Teacher.prototype.constructor = Teacher
var teacher1 = new Teacher(19,"女");
4、中介new function(){}空对象
var Fn = new function(){};
Fn.prototype = Person.prototype;
Teacher.prototype = new Fn();
Teacher.prototype.constructor = Teacher; //扩展封装
function Extend(ChildObj,ParentObj){
var Fn = new function(){};
Fn.prototype = ParentObj.prototype;
ChildObj.prototype = new Fn();
ChildObj.prototype.constructor = ChildObj;
ChildObj.uber = ParentObj.prototype; //直接指向父对象prototype属性
} //Teacher继承Person
Extend(Teacher,Person);
var teacher1 = new Teacher(19,'女');
5、拷贝继承(完全)
function Extend(ChildObj, ParentObj) {
var p = ParentObj.prototype;
var c = ChildObj.prototype;
for (var i in p) {
c[i] = p[i];
  }
  c.uber = p;
}
//Teacher继承Person
Extend(Teacher,Person);
var teacher1 = new Teacher(19,'女');

非构造函数“继承”(3种)

//原始
var Person = {
name: '小明'
}
var Teacher ={
age:19,
sex:'女'
}

这里我们如何可以让Teacher继承Person

1、object方法
function object(obj){
function Fn(){}
Fn.prototype = obj;
return new Fn();
}
var teacher1 = object(Person);
teacher1.age = 19;
teacher1.sex = '女';
2、浅拷贝方法
function extendCopy(ParentObj){
var c = {};
for(var i in ParentObj){
c[i] = p[i];
}
c.uber = p;
return c;
}
//使用extendCopy
var teacher1 = extendCopy(Person);
teacher1.age = 19;
teacher1.sex = '女';
3、深拷贝方法
function extendDeepCopy(ParentObj,ChildObj){
var ChildObj = ChildObj || {};
for(var i in ParentObj){
if(typeof ParentObj[i] === 'object'){
c[i] = (ParentObj[i].constructor === Array) ? [] : {};
extendDeepCopy(ChildObj[i],ParentObj[i]);
}else{
ChildObj[i] = ParentObj[i];
}
}
return ChildObj;
} //使用
var teacher1 = extendDeepCopy(Person1);
teacher1.age = 19;
teacher1.sex = '女';

本文版权归作者共有,欢迎转载,须保留此段声明,并给出原文链接,谢谢!

聊一聊Javasript继承的更多相关文章

  1. 聊一聊log4j2配置文件log4j2.xml

    一.背景 最近由于项目的需要,我们把log4j 1.x的版本全部迁移成log4j 2.x 的版本,那随之而来的slf4j整合log4j的配置(使用Slf4j集成Log4j2构建项目日志系统的完美解决方 ...

  2. C#中简单的继承和多态

    今天我们来聊一聊继承,说实话今天也是我第一次接触. 继承的概念是什么呢?就是一个类可以继承另一个类的属性和方法(成员) 继承是面向对象编程中的一个非常重要的特性. 好了,废话不多说,下面切入正题: 1 ...

  3. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  4. ( 转 ) 聊一聊C#的Equals()和GetHashCode()方法

    聊一聊C#的Equals()和GetHashCode()方法   博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. ...

  5. 聊一聊C#的Equals()和GetHashCode()方法

    博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. 最近在看Jeffrey Richter的CLR Via C#,在看 ...

  6. 谈谈JavaScript中继承方式

    聊一聊js中的继承 一.简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型 父级构造函数 function Parent(param) { this.name = 'parent' ...

  7. 聊一聊isinstance与type

    聊一聊isinstance与type 最近写代码的时候遇到了一个关于isinstance与type的坑,这里给大家分享下,如果大家也遇到了同样的问题,希望本文能为大家解决疑惑把. isinstance ...

  8. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

  9. 聊一聊Android的消息机制

    聊一聊Android的消息机制 侯 亮 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和消息机制,前者用于跨进程通信,后者用于进程内部通信. 从技术实现上来说,消息机制还是比 ...

随机推荐

  1. mybatis框架(5)---动态sql

    那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态S ...

  2. 理解Vue中的Render渲染函数

    理解Vue中的Render渲染函数 VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数.比如如下我想要实现 ...

  3. 微信小程序基于最新版1.0开发者工具分享-小试牛刀(视频)+发布流程

    第一章:小程序初级入门教程 小试牛刀[含视频] 视频地址:https://v.qq.com/x/page/i0554akzobq.html 这一章节中,我们尝试着写一个最简单的例子,包含 2 个静态页 ...

  4. go实例之轻量级线程goroutine、通道channel与select

    1.goroutine线程 goroutine是一个轻量级的执行线程.假设有一个函数调用f(s),要在goroutine中调用此函数,请使用go f(s). 这个新的goroutine将与调用同时执行 ...

  5. CSS3关于过渡效果的问题

    首先trasition:transform只是单单表示后面只要有含有的tranform的所有属性可以参与动画,而trasition:all表示后面所有动画属性都可以参动画,当父容器有relative时 ...

  6. Xamarin android使用Sqlite做本地存储数据库

    android使用Sqlite做本地存储非常常见(打个比方就像是浏览器要做本地存储使用LocalStorage,貌似不是很恰当,大概就是这个意思). SQLite 是一个软件库,实现了自给自足的.无服 ...

  7. ubuntu设置静态ip

    设置固定ip地址 >>>>>>>>>> ifconfig -a,  (注:p1p1为网卡名称) 配置静态ip vim /etc/networ ...

  8. Linux(CentOS6.5_X86.64)编译libjpeg出现“checking host system type... Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized”的解决

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢!   今天在编译libjpeg 的时候,遇到下面的报错: checki ...

  9. 小白的Python之路 day4 软件目录结构规范

    软件目录结构规范 为什么要设计好目录结构? "设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题.对于这种风格上的规范,一直都存在两种态度: 一类同 ...

  10. 冲顶大会APP技术选型及架构设计

    我在1月4日看到虎嗅推送"王思聪撒币"的消息,然后开始推敲背后技术.其中涉及直播流.实时弹幕.OAuth2.0开放授权.SMS api.Push网关.支付接口等业务,其技术实现并不 ...