javascript中创建对象和实现继承
# oo
##创建对象
1. 原型、构造函数、实例之间的关系
* 原型的construct->构造函数;调用isPrototypeOf(obj)方法可以判定和实例的关系;
* 构造函数的prototype->原型;
* 实例的__proto__ ->原型(仅在chrome,safari,Firefox中存在,而共有的是[[prototype]]);用getPrototypeOf()方法可以返回[[prototype]]的值;
* 构造函数后构造函数的‘子类’new产生一个实例,可以用instanceOf 操作符来检测构造函数是否出现在原型链上。
2. 说明:
* 一个函数在声明之后就会有prototype对象,对象的constructor属性所存放的指针指向该函数。
* 对原型进行赋值,就让这个prototype中的指针指向了一个新的对象,里面的constructor属性自然会丢失。如果把父类的值赋给了它,那么这个constructor就是父类实例的值。父类实例并没有这个属性,于是继承父类的原型中的constructor。所以,子类构造函数的(this.constructor)的值通过这样的步骤获得:
子类实例(没有)--子类原型 (没有)--父类原型(有,为父类构造函数)
3. new关键字的理解
new的作用就是新建一个作用域,将this指向该作用域,然后执行函数中的代码。不用new关键字,那么this将指向globle对象,在浏览器中是window对象。
4. 检测对象和属性的关系
(1)
* in操作符 能够访问该属性
* hasOwnProperty() 存在实例中
* !obj.hasOwnProperty() && in 存在原型中
(2)
* for-in循环 枚举出 包含实例中的属性和原型中 可枚举的属性;
* Object.keys(obj) 返回一个数组 可枚举的实例属性;
* object.getOwnPropertyNames(obj) 得到所有实例属性,无论是否可以枚举;
##实现继承
1. 原型链继承
2. 借用构造函数(又叫伪造对象,对象冒充法,经典继承等)
3. 组合继承(又叫伪经典继承)
function Anm(name,age) {
this.name = name;
this.age = age;
}
Anm.prototype.sayBye = function () {
console.log(this.name + ' say bye to you!');
};
function Dog(food, name, age) {
//从父类中,通过call或apply方法继承属性
Anm.call(this, name, age);
this.food = food;
}
//子类通过设置原型等于父类的一个实例的方式,继承方法
Dog.prototype = new Anm();
Dog.prototype.constructor = Dog;
Dog.prototype.sayHello = function() {
console.log(this.name + ' say hello to me!')
};
dog1 = new Dog('shit', '小黄狗', 15);
console.log(dog1); //{name: "小黄狗", age: 15, food: "shit", constructor: function, sayHello: function…}
dog1.sayBye(); //小黄狗 say bye to you!
dog1.sayHello(); //小黄狗 say hello to me!
这种继承,能够让子类产生的实例拥有自己的属性,又可以从父类的原型上面继承得到公用的方法。所以成为javascript中最常用的继承模式。
4. 原型式继承
function Anm(klass) {
this.klass = klass;
}
var dog1 = Object.create(gou, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: '小黄'
},
birthyear: {
value: 2012
},
age: {
get: function () {
var thisTime = new Date();
return thisTime.getFullYear() - this.birthyear;
}
}
});
console.log('修改前的对象');
console.log(dog1); //Object {name: "小黄", birthyear: 2012, age: 3, klass: "狗狗"}
dog1.name = '小李';
dog1.birthyear = 2010;
console.log('修改后的对象'); //Object {name: "xiaoli", birthyear: 2012, age: 3, klass: "狗狗"}
console.log(dog1);
Object.create()方法接受两个参数,第一个是作为原型的对象,第二个是为新队想定义额外属性的对象,以JSON格式,每一个要新增的属性都是该对象中一个属性,它的值也是一个描述符对象。
属性有数据属性(如上面的name和birthyear)和访问器属性(如上面的age),如果只写入一个特性,其余特性的值将会被设置为false。所以上面的birthyear是无法改动的。
这种方式可以在指向让一个对象与另一个对象保持类似的情况下使用,不用去进行构造函数的创建。
5. 寄生式继承
上面的Object.create()方法额可以只创第一个参数,然后在对返回的函数添加属性,再把这整个过程封装起来,这种方式叫作寄生式继承。
6. 寄生组合式继承
子类的原型在Dog.prototype = new Anm()过程中,为它添加了Anm中属性klass(值为undifiend),同时Dog构造函数中,同样为实例添加了klass,相当于在原型和实例中都创造了属性。如果属性很多的话,这是一种浪费。如果能够不让子类的原型产生这些属性,直接让他的[[prototype]]指向父类的原型的话,那么就能够继承父类的方法了。
我们先封装一个方法:
function inheriyPrototype(subType, superType) {
var newPrototype = Object.create(superType.prototype);
subType.prototype = newPrototype;
newPrototype.constructor = subType; //重写了subType.prototype后丢失了自己的constructor,这里进行补写
}
这个方法让子类不通过父类的实例赋值,而是让它的[[prototype]]直接指向父类的实例。
实际上,这个子类的原型是一个空函数创建的,这个空函数的原型等于父类的原型。所以就让这个空函数的实例只有一个[[prototype]],再把这个实例赋值给了子类的原型,加上constructor属性。就实现了不创造多余属性的目的。
接下来:
function Anm(klass) {
this.klass = klass;
}
Anm.prototype.sayKlass = function () {
console.log(this.klass);
};
function Dog(name, klass) {
Anm.call(this, klass);
this.name = name;
}
inheriyPrototype(Dog, Anm);
var dog1 = new Dog('小黄', '犬科动物');
console.log(dog1); //Dog {klass: "犬科动物", name: "小黄", constructor: function, sayKlass: function}
dog1.sayKlass(); //犬科动物
console.log(Dog.prototype); //Dog {constructor: function, sayKlass: function}
console.log(Dog.prototype.isPrototypeOf(dog1)); //true
console.log(Anm.prototype.isPrototypeOf(dog1)); //true
现在很多程序员普遍认为寄生组合式是最理想的继承范式。在YUI中的一些方法上已经开始在使用了。
javascript中创建对象和实现继承的更多相关文章
- 【转】JavaScript中的原型和继承
请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- 谈谈javascript中的prototype与继承
谈谈javascript中的prototype与继承 今天想谈谈javascript中的prototype. 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性 ...
- javascript中创建对象的方式总结
javascript中创建对象的方式总结 具体代码如下: //创建对象的方式: //创建方式一 var person=new Object(); person.name='jack'; person. ...
- javascript中创建对象的几种不同方法
javascript中创建对象的几种不同方法 方法一:最直白的方式:字面量模式创建 <script> var person={ name:"小明", age:20, s ...
- JavaScript中创建对象的三种方式!
JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...
- javascript中的对象之间继承关系
相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象 ...
- Javascript中的prototype与继承
通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表.javascript创建对象时采用了写时复制的理念. 只有构造器才具有prototype属性,原型链继承 ...
- 深入 JavaScript 中的对象以及继承原理
ES6引入了一个很甜的语法糖就是 class, class 可以帮助开发者回归到 Java 时代的面向对象编程而不是 ES5 中被诟病的面向原型编程. 我也在工作的业务代码中大量的使用 class, ...
随机推荐
- 设置随机 User-Agent
本文转载自以下网站: Scrapy 中设置随机 User-Agent 的方法汇总 https://www.makcyun.top/web_scraping_withpython14.html 一行代码 ...
- 自学python 第三天
#!/usr/bin/env python# -*- coding:utf-8 -*- # name = "***"# if "*" in name:# pri ...
- Atcoder AGC031B Reversi (DP计数)
简单的计数题.(总算做出一道AGC的B题了,然而这场比赛我忘记打了233333) 题目链接: https://atcoder.jp/contests/agc031/tasks/agc031_b 题意: ...
- Basic Memory Structures
Basic Memory Structures The basic memory structures associated with Oracle Database include: System ...
- JavaScript向window onload添加加载函数
有时候我们需要在页面加载事件后完成一些函数操作,对于函数比较多的情况下可以写一个统一的加载函数 .本函数来自于JavaScript DOM 编程艺术: function addLoadEvent(fu ...
- 0912MySQL 执行计划explain详解
转自http://blog.itpub.net/29773961/viewspace-1767044/ 该博客内容是比较全的,虽然写的比较晦涩,多读几遍还是不错的 explain命令是查看查询优化器如 ...
- wifi断线问题
近期在项目中,遇到wifi常常断线现象,平台是Android平台,现象是:连接wifi后,长时间播放视频,会出现wifi断开,界面上WiFi图标显示打叉,请问有WiFi方面的行家朋友,有没有办法来检測 ...
- ant 调用
博客园 首页 新随笔 联系 订阅 管理 [图文] 使用ant编译和发布java项目 开发JavaEE项目经常会碰到修改代码后,项目没有重新编译的问题.老大给指明了一个解决办法:用ant ...
- SecureCRT图形界面(通过设置调用Xmanager - Passive程序)
首先,在server进行设置 假设server是图形化界面启动的,xhost +命令能够不用运行 [root@test ~]# xhost + xhost: unable to open displ ...
- setResult详解
startActivityForResult与startActivity的不同之处在于:1.startActivity( ) 仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startAct ...