一句话:js中的继承用原型链实现.
先说一下原型 , 每个function都有一个prototype属性,称为原型,其实就一个Object对象,这玩意用来存放函数以及共享的变量,
就像是其他语言中的class: 只想说js中的东西比c++简洁多了
访问原型的方式 : 对象.__proto__ / 构造函数.prototype , js中任何一个对象都有__proto__, 是一个函数就有prototype
dom节点中的原型:
<script type="text/javascript">
window.onload = function(){
var div = document.getElementById("id");
var pro = div.__proto__;
while(pro){
console.log(pro.constructor)
pro = pro.__proto__
}
}
</script>
<body>
<div id = "id"></div>
</body>
通过js内置对象中的prototype 看看这东西:
//调用String 构造函数
var s = new String("nihaoa");
//有没有indexOf属性呢?
console.log(s.hasOwnProperty("indexOf"));//false
//明明可以调用, 为什么没有这个属性?
console.log(s.indexOf("o"))
//同上,明明可以调用,为什么自身没有这个属性?
//那么这些函数藏在哪里了?
var d = new Date();
console.log(d.getDate())
console.log(d.hasOwnProperty("getDate"))
上面明明可以调用的函数为什么在自身对象中找不到 ?
他们都藏在了prototype中 . prototype指向的是一个对象. 这个对象默认就是一个new Object();
访问这个原型对象的方式一般就2种:
第一种: 通过构造函数的名字 ,比如 : String.prototype
第2种 : 通过一个对象 __proto__ ( 非标准, 即每个浏览器可能有自己变量名 ), 下面全部使用__proto__,如果你的浏览器不支持
__proto__ ,自己去查一下;
例子 , 沿用上面的代码:
//通过对象的方式 , __proto__ 属性不一定在每个浏览器都适用, 非标准
console.log(s.__proto__.hasOwnProperty("indexOf"))
//通过构造函数名来访问 , String.prototype
console.log(String.prototype.hasOwnProperty("indexOf"))
//Object.getOwnPropertyNames 枚举对象的属性
console.log(Object.getOwnPropertyNames(String.prototype))
现在知道这些函数/方法都藏在了prototype指向的一个对象中,
给原型中添加一个函数:
//给原型添加1个函数, 原型本身就1个Object ,因此随意添加即可;
String.prototype.print_to_console = function(){
console.log(this)
}
var s = new String("12345");
//调用这个刚刚添加的函数
s.print_to_console()
可以看到通过修改原型,可以随意添加任意函数/方法
自定义构造函数:
function x(){
}
console.log(x.prototype) //输出一个Object
console.log(x.prototype.constructor) //输出了自己的构造函数
prototype : 指向一个Object 对象,其实就跟你 var o = new Object() 类似. 每个function对象都有这么一个属性 ,比如String.prototype , 只要是一个函数对象都会有这个属性,指向一个原型;
原型对象中一般情况下都有一个 constructor 与 一个 __proto__;
constructor. 指回自身构造函数,啥意思 ?
function x(){
}
console.log(x.prototype.constructor)
//以下模拟 原型
//自己创建一个对象
var like_prototype = {};
//添加一个属性 ,指向x
like_prototype.constructor = x;
console.log(like_prototype.constructor)
这玩意用来干嘛 ?
用来维持实例对象与构造函数的关系的
function x(){}
var o = new x();
//这个对象是否通过这个构造函数生成的?
console.log(o.constructor == x) // o.__proto__.constructor
原型长什么样?
默认情况下有2个属性, 一个指向构造函数 , 还有一个__proto__属性,每个对象都有一个__proto__属性指向原型或用于继承(后面说);
从这里开始, 唯一需要记住的是, 每个对象中都隐藏着一个属性 __proto__ ,指向一个原型;
var obj = {constructor:x , __proto__ : object};
__proto__ 是什么? 先简单看一下, 指向原型