js中原型,原型链,原型链继承的个人理解
一、什么是原型?
每一个javascript对象在创建的时候就会有一个与之关联的对象B产生,对象B就是所说的“原型”。
1)原型也是一个对象,其他对象可以通过原型实现属性继承,
2)js中的继承就是基于原型的继承;
3)所有对象在默认情况下都有一个原型,因为原型也是一个对象,所以每 个原型自身又有一个原型,默认的对象原型在原型链的顶端;
二、函数的原型对象
创建一个函数A,那么浏览器就会在内存中创建一个对象B,而且每个函数都会默认有一个prototype属性指向这个对象(即:prototype属性的值是这个对象),而对象B就是函数A的原型对象,简称函数的原型。对象B默认会有一个constructor属性指向函数A(即:constructor属性的值是函数A)。
三、原型相关属性
1.prototype:存在于构造函数中,指向这个构造函数的原型对象
2.__proto__:存在于实例对象中,指向这个实例对象的原型对象
3.constructor:存在于原型对象中,指向构造函数
举例:
function Pro(name,age){
this.name=name;
this.age=age;
}
var pro1=new Pro();
var pro2=new Pro();
关系:
pro1.__proto__==pro2. __proto__;
pro1.__proto__==Pro.Prototype;
Pro.prototype.constructor==Pro();
Pro.prototype.__ptoto__==Object.prototype;
Object.prototype.constructor==Object();
结论:
1)pro1.__proto__和pro2.prototype都指向构造函数Pro的原型对象;
2)如果使用new Person()创建多个对象,则多个对象都会同时指向Person构造函数的原型对象;
什么是原型链?
由图引出原型链的概念:
每个构造函数都一个prototype属性指向自身的原型,而由该构造函数创建的实例对象也都有一个__proto__属性指向该构造函数的原型,而构造函数的原型也是一个对象,它也会有一个__proto__属性指向自己的原型,这样层层深入,直到Object的原型,从而形成了原型链。
一个实例,至少应该拥有指向原型的proto属性,这是JavaScript中的对象系统的基础。不过这个属性是不可见的,我们称之为“内部原型链”,以便和构造器的prototype所组成的“构造器原型链”(亦即我们通常所说的“原型链”)区分开
四、原型方法
1. getPrototypeOf():获取一个对象的原型
格式:Object. getPrototypeOf(对象)
2. setPrototypeOf():设置一个对象的原型
格式:Object. setPrototypeOf(对象)
3.hasOwnProperty():用于判断一个属性是本地属性,还是继承梓prototype对象的属性
格式:对象. hasOwnProperty(’属性名’):
4.isPrototypeOf( ):判断对象a是否存在于另一个对象prototypeObject的原型链中(只有存在继承关系时该方法才有用)
格式:prototypeObject.prototype.isPrototypeOf(a)
5.instanceof:判断a是否是b的实例对象
格式:a.instanceof.b
五、使用prototype扩展对象的原型属性和原型方法
1.当对象被创建后,就可以使用prototype来扩展对象
Obj.prototype.method=function(){}
举例:
Function car(){};//声明一个构造函数,即创建了一个对象
Car prototype.color=’red’;
六、创建对象的新方法
Object.create(obj):obj是要使用的原型,即要被继承的对象
举例:
Var car={name:“奔驰”};
Var car1=Object.create(car);
给对象扩展属性和方法:
1. 对象可以继承原型的属性,也可以扩展出自己的属性和方法
举例:
varcar={
name:'玛莎拉蒂',
price:'500W',
}
var car1=Object.create(car);
car1.color='red';//定义自有属性
car1.name='法拉第 ';//重新定义一个自有的name属性
car1.run=function(){//扩展一个自有方法
console.log('四驱引擎驱动');
}
console.log(car1.price);//继承原型的name属性
console.log(car1.name);//法拉第
console.log(car1.color);//red
car1.run();
//原型属性MaxSpeed
Object.getPrototypeOf(car1).MaxSpeed='300公里/小时';
//等价于car1.__proto__.MaxSpeed='300公里/小时';
//给原型扩展一个新方法,所有子级对象可以继承该方法
Object.getPrototypeOf(car1).stop=function(){
console.log('停车');
}
var car2=Object.create(car);
console.log(car2.name);//继承原型原有的属性
//color是car1的自有属性,其他子级对象无法继承该属性
console.log(car2.color);
console.log(car2.MaxSpeed);//继承新增加的原型属性
car2.stop();//继承新扩展的方法stop
//修改原型属性name,使得所有子级对象的name属性值全部改变
Object.getPrototypeOf(car1).name='比亚迪';
var car3=Object.create(car);
console.log(car2.name);
console.log(car3.name);
delete car1.name;//删除自有属性
console.log(car1.name);//比亚迪
七、原型链的继承
这种方法最常用,安全性也比较好。我们先定义两个对象:
function Animal(name){
this.name = name;
}
function Dog(age) {
this.age = age;
}
var dog = new Dog(2);
要构造继承很简单,将子对象的原型指向父对象的实例(注意是实例,不是对象)
Dog.prototype = newAnimal("wangwang");
这时,dog就将有两个属性,name和age。而如果对dog使用instanceof操作符
console.log(doginstanceof Animal); // true
console.log(dog instanceof Dog); // false
这样就实现了继承,但是有个小问题
console.log(Dog.prototype.constructor ===Animal); // true
console.log(Dog.prototype.constructor ===Dog); // false
可以看到构造器指向的对象更改了,这样就不符合我们的目的了,我们无法判断我们new出来的实例属于谁。因此,我们可以加一句话:
Dog.prototype.constructor = Dog;
再来看一下:
console.log(dog instanceof Animal); // false
console.log(dog instanceof Dog); // true
这种方法是属于原型链的维护中的一环
例2完整代码:实现让Child构造函数的原型继承Parent.prototype的getName方法
function Parent(name){
this.name=name
}
function Child(name){
this.name=name
}
Parent.prototype.getName=function(){
return this.name;
}
Child.prototype=new Parent();//实现继承
Child.prototype.constructor=Child;//原型链的维护
var parent=new Parent('parent');
var child=new Child('child');
console.log(parent.getName());
console.log(child.getName());
console.log(Child.prototype.constructor==Child);
js中原型,原型链,原型链继承的个人理解相关推荐
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
- Js中的作用域和作用域链
Js中的作用域和作用域链 前言 阅读本文,请先阅读:Js中的函数相关:创建函数的三种方式.函数的形参和实参.返回值.return.break.continue的区别.重载和arguments.匿名函数 ...
- js中的对象、原型链机制、构造函数
一.在js中创建对象的方式 //一.字面量或直接量创建对象var obj1 = {name:"zs",age:12}; //二.通过new来创建对象var obj2 = new O ...
- JS 中通过对象关联实现『继承』
JS 中继承其实是种委托,而不是传统面向对象中的复制父类到子类,只是通过原型链将要做的事委托给父类. 下面介绍通过对象关联来实现『继承』的方法: Foo = {// 需要提供一个 init 方法来初始 ...
- JS 中对象的简单创建和继承
对象的简单创建 1.通过对象直接量创建 比如 var obj = {}; 2.通过new 创建 比如 var obj = new Object(); // 相当于var obj = {}; var a ...
- JS中“创建对象”及“通过原型创建对象”浅析
一.创建对象的几种方式 1.各自独立声明模式 var box1 = new Object(); //声明第一个对象并给各属性赋值 box1.name = 'Lee'; box1.age = 100; ...
- JS中的类,类的继承方法
大牛请无视此篇! 首先我们定义一个类,方法很简单,就像我们定义函数一样,只不过我们为了与函数区分,名称首字母要大写,看代码: function Person (){} 这就是一个很简单的Poson类, ...
- 关于JS中变量提升的规则和原理的一点理解(一)
关于变量提升,以前在一些教程和书籍上都听到过,平时开发中也知道有这个规律,但是今天突然在一个公开课中听到时,第一反应时一脸懵逼,然后一百度,瞬间觉得好熟悉啊,差点被这个概念给唬住了,不信我给你 ...
- js的作用域链,原型链,以及闭包函数理解
代码一: this.number = 10 function a() {this.number = 20 } a.prototype.init = () => console.log(this. ...
- 前端 ---JS中的面向对象
JS中的面向对象 创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 JS ...
最新文章
- MSCKF理论推导与代码解析
- 手机超广角拍摄软件_桂林好的拍摄短视频手机软件
- pytorch 数据加载性能对比
- java publickey_Java中RSAPublicKey在不同平台的差异性
- [CocoaPods]常见问题
- java lambda 多个参数_Java Lambda行为参数化
- vim中括号自动补全
- [Ext JS] 3.3 树(Tree)的定义和使用
- C Primer Plus 第8章 字符输入/输出和输入确认 8.11 编程练习答案
- Spring 数据处理框架的演变
- Andrew Ng机器学习课程17(1)
- GAN(生成对抗网络)有一本实战书出版了,了解下?
- 软件工程项目—个人通讯录管理系统
- lempel ziv matlab,使用Lempel-Ziv压缩
- 比较有意思的.NET反调—《.NET在蹉跎中一路前行》
- 莫安迪2019平面设计作品展示
- compiz在debian上的安装和使用
- 【大数据】什么是大数据
- Android 程序员必须掌握的三种自动化测试方法
- 当微信小程序遇上filter~