js原型解析
原型
在JavaScript中,每个对象都保持着一块隐藏的状态: 一个对另一个对象的引用,也被称作原型
Js中对象的属性分为两种存在形态,一种在实例中,一种在原型中
- ①不存在于实例,不存在于原型
- ②存在于实例,不存在于原型
- ③不存在于实例,存在于原型
- ④存在于实例,存在于原型
hasOwnPrototype()接受一个字符串格式的属性名称,存在实例中的会返回true,否则返回false
function People() { this.age = 12 }
People.prototype.name = "wk";
var p1 = new People();
console.log(p1.hasOwnProperty("age")); //true
console.log(p1.hasOwnProperty("name")); //false
p1.name = "newwk";
console.log(p1.hasOwnProperty("name"));//true
in操作符无论属性是存在实例本身中,还是原型中都会返回true,否则返回false
!object.hasOwnProperty(name) && (name in object)表示只存在于原型中
当使用对象的方法或属性时,对象会在一步一步通过__proto__向上寻找,找到最近的则是最终的获取到的方法或属性。
Object.prototype没有__proto__,是原型链的顶峰
对象通常继承的constructor均指代它们的构造函数,而构造函数是类的“公共标识”。即constructor可用来判断对象所属的类。
用instanceof也可判断对象的类,但是有自身的缺陷
function Xxx()
{
this.name = '';
}
Xxx.prototype.add = function () { };
var a = new Xxx();
console.log(Xxx.prototype);
console.log(Object.getPrototypeOf(a));
//Object.getPrototypeOf 函数才是查看对象原型的推荐方法
prototype只不过是一个包含constructor属性的Object对象,其中constructor属性是指向当前function的一个指针
自定义类最常见的方式 构造函数模式加混合模式
function MMy() {
this.name = name;
}
var m = new MMy();
创建好MMy后,MMy除了name属性外,还有一个prototype属性,这个属性指向的是一个对象
它创建的实例m对象除了有属性name外也有一个隐藏的属性__proto__,这个__proto__和MMy.prototype指向同一个对象
应该说m.__proto__指向的是MMy.prototype指向的对象,这个对象有一个constructor属性,还有__proto__属性等
此时的constructor指向function MMy(),__proto__指向的是Object;
MMy.prototype =
{
//不加这句的话,p.__proto__,即MMy.prototype指向的是Object,加上就变成MMy了
constructor: MMy,
sayname: function () {
console.log('123');
}
}
function MMx()
{
this.age = 34;
}
MMy.prototype = new MMx();
当新显示的加MMy.prototype={},显然改变了原来的MMy.prototype,覆盖了,MMy.prototype现在是一个新的对象,所以这时MMy.prototype指向的是Object,这时候实例化对象m也会指向Object,所以显示的把MMy.prototype的constructor纠正过来
var m = new MMy();
MMy.prototype.constructor = MMy;
console.log(MMy.prototype); //是MMy本身
console.log(m.constructor); //是MMy本身
m每个对象都有一个_proto_属性,查找toString()方法时,首先会从MMy方法中查找,发现没有,然后从m._proto_属性中,因为m._prototype=MMy.prototype,而MMy.prototype只有一个属性.所以也没找到toString()方法,然后沿着Person.prototype._proto__找到了Object,在这里我们就找到了toString()方法。
js引擎查找过程是先从本函数查找,如果找到就return,找不到继续通过__proto__往上找,而prototype属性是通过__proto__找到的