您的位置:首页 > Web前端 > JavaScript

JavaScript原型对象prototype

2017-05-23 19:26 447 查看

使用字面量创建原型对象

使用构造函数创建原型对象和使用字面量创建对象在使用上基本相同,但有区别:字面量创建的方式使用constructor属性不会指向实例,而是指向Object,原因也很简单,因为用字面量表示原型的时候,用了一个{},既然用了{},那么就是创建了新的对象,相当于重新new了一个Object,这个对象也会自动获取constructor属性,所以,新对象(理解为构造函数)的constructor重写了Box原来的constructor,因此会指向新对象,那个新对象没有指定构造函数,默认就是Object。而不是原来的Box了,这也导致了一些问题:没有指向原来的构造函数对象.





function Box() {}

Box.prototype = {
name: 'lee',
age:100,
run:function() {
return this.name + this.age + ' is running...';
}
};
var box = new Box();
console.log(box.constructor);
//function Object() { [native code] } ,根本不是"function Box() {}"


难道就没有解决方案了吗?当然有!强制添加 constructor : Box

function Box() {}

Box.prototype = {
constructor:Box,//强制指向Box,当然也可以强制指向Array等玩玩也可以
name: 'lee',
age:100,
run:function() {
return this.name + this.age + ' is running...';
}
};
var box = new Box();
console.log(box.constructor);
//function Box() {}


重写原型对象

function Box() {}

Box.prototype = {
constructor: Box,
name: 'lee',
age:100,
run:function() {
return this.name + this.age + ' is running...';
}
};
//重写原型对象
Box.prototype = {
age:200  //这里不会保留之前原型的任何信息了,
//把原来的原型对象和构造函数对象实例之间的关系切断了
};

var box = new Box();
console.log(box.run());
//ERROR : Uncaught TypeError: box.run is not a function


原型对象不仅可以再自定义构造函数的情况下使用,ECMAScript内置的引用类型都可以使用这种方式,并且内置的引用类型也使用了原型

var box = [3,6,1,4,9,33,25];
//box.sort()是哪里来的?
//查看sort是否是Array原型对象里的方法
console.log(Array.prototype.sort);//function sort() { [native code] }
//我们是否可以扩展内置的引用类型呢?比如扩展String,添加一个方法
//当然可以,先判断,如果没有,就可以diy扩展
console.log(String.prototype.addstring);//undefined
String.prototype.addstring = function(str) {
return this + str;
};
console.log('guoyu'.addstring(', how are you!'));






判断一个对象实例是否指向了对象的原型对象,基本上只要实例化了,它是自动指向的

function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
var box2 = new Box();
var obj = new Object();
console.log(Box.prototype.isPrototypeOf(box1));//true
console.log(Object.prototype.isPrototypeOf(box1));//true
//box1显然是指向了Box的原型
console.log(Box.prototype.isPrototypeOf(obj));//false
//obj肯定不指向Box,两者没关系


原型模式的执行流程(先实例再原型)

先查找构造函数实例里的属性或方法,如果有立即返回;

如果构造函数实例里没有,则去它的原型对象找,如果有就返回;

function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
box1.name = 'Jack';
console.log(box1.name);//Jack


function Box() {
this.name = 'Jack';//这里也是实例
}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
console.log(box1.name);//Jack


那有的时候就想访问原型,怎么办?可以删除实例中的属性!

function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
box1.name = 'Jack';
console.log(box1.name);//Jack
delete box1.name;
console.log(box1.name);//guoyu


如何判断属性是在构造函数实例里还是原型里?hasOwnProperty()

function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
console.log(box1.hasOwnProperty('name'));//false


function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
box1.name = 'James';
console.log(box1.hasOwnProperty('name'));//true


function Box() {
this.name = 'TTT';
}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
console.log(box1.hasOwnProperty('name'));//true


in 操作符会在通过对象能够访问给定属性时返回true,无论属性存在于实例还是原型中,所以结合hasOwnProperty就能分辨出属性是否在原型中

判断,只有原型中才有的属性,方法封装如下:

function isProperty(obj, property) {
return !obj.hasOwnProperty(property) && (property in obj);
}


function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
box1.name = 'Kobe';
function isProperty(obj, property) { return !obj.hasOwnProperty(property) && (property in obj); }

alert(isProperty(box1, 'name'));//false


function Box() {}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
function isProperty(obj, property) { return !obj.hasOwnProperty(property) && (property in obj); }

alert(isProperty(box1, 'name'));//true



function Box() {
this.name = '';
}
Box.prototype.name = 'guoyu';
Box.prototype.age = 20;
Box.prototype.run = function () {
return this.name + this.age + 'is running...';
};
var box1 = new Box();
function isProperty(obj, property) { return !obj.hasOwnProperty(property) && (property in obj); }

alert(isProperty(box1, 'name'));//false


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息