javaScript中的prototype与_proto_
来源:互联网 发布:安卓备份软件 编辑:程序博客网 时间:2024/06/13 18:48
这几天读了JavaScript设计模式的继承,开始对于其中的类式继承和原型式继承中的prototype属性百思不得其解,但后来的查阅和实践让我对他更深层次地理解,纯属个人理解,有不对的内容还不吝赐教。
Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。
每个对象都有一个原型对象,但这并不意味着每个对象都有一个一个prototype属性,只有函数对象才有这个对象。如:
var b = {
name: 'hello world!'
}
b是一个对象字面值,不是一个函数对象,其实它相当于Object的一个实例。
在创建一个对象时,JavaScript会自动将其原型对象设置为其构造函数的prototype属性所指的对象。应该注意的是,构造函数本身也是一个对象,它也有自己的原型对象,但这个原型不是它的prototype所向的那个对象。作为一个对象,其构造函数是Function,因此,构造函数的原型对象实际上是Function.prototype所指向的对象。
1.类式继承中的代码如下:
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
}
function Author(name, books){
Person.call(this, name);
this.books = books;
}
Author.prototype = new Person();
Author.prototype.constructor = Author;
Author.prototype.getBooks = function(){
return this.books.toString();
}
var a = new Author('hudie', []);
alert(a.getName() + 'write:' + a.getBooks());
一开始对Author.prototype = new Person()这一行很不解,为什么不直接设置成Author.prototype = Person,后来结果完全不一样,如下图所示:
且提示错误:a.getName is not a function,这是因为你相当于把Person这个对象的引用传递给了Author.prototype,后面对Author.prototype.constructor进行修改,这相当于把Person也改变了,所以是不行的,且Author的实例化对象a的中的_proto_为空,所以无法调用getName()。而如果是Author.prototype = new Person(),结果会是:
__proto__是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。
new的过程拆分成以下三步:
(1) var p={}; 也就是说,初始化一个对象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是说构造p,也可以称之为初始化p
沿着原型链向上追溯,就是使用__proto__属性来链接到原型(也就是Person.prototype)进行查找相应的方法和属性,上面Author的__proto__的prototype中__proto__指向Person.prototype所以可以调用Person的getName方法。
看看Author的实例化对象就很简单了(注意Author的getBooks方法应该在继承代码后,不然会被Person.prototype覆盖):
2.为了方便写一个extends函数重构代码,则如下:
function extend(subClass, superClass){
var F = function(){};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
}
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
}
function Author(name, books){
Person.call(this, name);
this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function(){
return this.books.toString();
}
var a = new Author('hudie', []);
alert(a.getName() + 'write:' + a.getBooks());
与前面一样,它设置了prototype,然后将其constructor重设为恰当的值。作为一个改进,它添加了一个空函数F,并将它创建的一个对象实例插入原型链中。这样做可以避免创建超类的新实例,因为它可能会很庞大,而且有时超类的构造函数有一些副作用,或者会执行一些需要大量计算的任务,比较new person()和new F()便可看出:
显而易见,new F()没有name属性了。
附注:主要参考了JavaScript设计模式 Ross Harmes、Dustin Diaz。
- javaScript中的prototype与_proto_
- JavaScript中的_proto_与prototype的关系
- JavaScript _proto_与prototype
- prototype与_proto_
- js之prototype与_proto_
- 原型与原型链prototype与_proto_
- 深入分析js中的prototype,_proto_,constructor
- JS中原型链中的prototype与_proto_的理解和区别
- javascript prototype 、_proto_和constructor之间的关系
- javascript学习——constructor、prototype、_proto_的区别
- JavaScript中_proto_和prototype的区别和关系?
- prototype _proto_ new的过程
- 深入了解javascript中的prototype与继承
- 谈谈javascript中的prototype与继承
- JavaScript中原型学习基本理解(原型链: prototype _proto_)(二)
- instanceof与typeof(写一个方法判断数据类型),prototype与_proto_
- JS原型与原型链终极详解_proto_、prototype及constructor
- Js中原型与原型链及_proto_和prototype的关系
- ArrayList与LinkedList
- Android Studio修改字体大小
- BroadCast广播机制
- smartsvn9破解及license文件
- RISC-V
- javaScript中的prototype与_proto_
- 前后端分离的想法
- C++ Primer Chapter 9-3
- mjpg streamer(OpenWRT)
- 系统的简单注解
- 双向链表的c++实现
- JAVA多线程—Lock&Condition实现线程同步通信
- android网络请求失败原因
- soa面向服务--案例(中)