1⃣️属性
刚接触prototype、constructor、proto这三个玩意儿的时候,是不是有点儿傻傻分不清楚的感觉?下面来简单的说下。
举?
function Foo(){}; var f1 = new Foo;
1.先了解下什么是构造函数
用来初始化新创建的对象的函数是构造函数。在上面的代码中,函数Foo是构造函数
2.实例对象
通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象,在上面的代码中,new Foo 就是一个实例对象,用变量f1存储了它
3.下面上正主儿
1)prototype(原型对象)
构造函数有一个prototype属性,指向实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。(经常使用原型对象来实现继承)
function Foo(){}; Foo.prototype.a = 1; var f1 = new Foo; var f2 = new Foo; console.log(Foo.prototype.a);//1 console.log(f1.a);//1 console.log(f2.a);//1
2)constructor
原型对象有一个constructor属性,指向该原型对象对应的构造函数
function Foo(){}; console.log(Foo.prototype.constructor === Foo);//true
3)__proto__
这个东西并不是标准的原型,它是一些浏览器提供的一个查看prototype的接口,多用于调试,prototype才是标准原型,可用在代码中。
它是被实例对象中的一个属性。
在chrome调试中,函数的原型可以用prototype查看,而__proto__可以看所有对象的原型。
function Foo(){};
var f1 = new Foo;
console.log(f1.__proto__ === Foo.prototype);//true
三者关系?
// 声明构造函数 function Person(name, age) { this.name = name; this.age = age; } // 通过prototye属性,将方法挂载到原型对象上 Person.prototype.getName = function() { return this.name; } var p1 = new Person('tim', 10); var p2 = new Person('jak', 22); console.log(p1.getName === p2.getName); // true
2⃣️方法
1.hasOwnProperty(propertyName)
hasOwnProperty方法接收一个字符串参数,该参数表示属性名称,用来判断该属性是否在当前对象实例中,而不是在对象的原型链中。直白点儿说就是检测当前对象有没有某个属性,返回一个布尔值
var arr = []; console.log(arr.hasOwnProperty("length"));//true console.log(arr.hasOwnProperty("hasOwnProperty"));//false
2.isPrototypeOf(Object)
isPrototype方法接收一个对象,用来判断当前对象是否在传入的参数对象的原型链上,返回一个布尔值
function MyObject() {} var obj = new MyObject(); console.log(Object.prototype.isPrototypeOf(obj)); // true
这个检测的就是Object的原型对象是否在obj的原型链上,MyObject是继承自Object对象的,而在JS中,继承是通过prototype来实现的,所以Object的prototype必定在MyObject对象实例的原型链上。所以结果是肯定的
MyObject是继承自Object对象的,而在JS中,继承是通过prototype来实现的,所以Object的prototype必定在MyObject对象实例的原型链上。
3.propertyIsEnumerable(prototypeName)
prototypeIsEnumerable用来判断给定的属性是否可以被for..in语句给枚举出来(个人感觉可以理解为是否可以被for..in语句遍历到)出来,返回一个布尔值
var obj = { name: "objName" } for (var i in obj) { console.log(i); // name }
console.log(obj.propertyIsEnumerable("constructor"));//false
执行这段代码输出字符串“name”,这就说明通过for…in语句可以得到obj的name这个属性,但是,obj的属性还有很多,比如constructor,比如hasOwnPrototype等等,它们并没有被输出,说明这些属性不能被for…in给枚举出来,可以通过propertyIsEnumerable方法来得到。
4.toLocaleString()
toLocalString方法返回对象的字符串表示,和代码的执行环境有关。
var obj = {}; console.log(obj.toLocaleString());//[object Object] var date = new Date(); console.log(date.toLocaleString());//2016/2/28 下午1:39:27 输出的就是本地的时间
5.toString()
toString用来返回对象的字符串表示
var obj = {}; console.log(obj.toString());//[object Object] var date = new Date(); console.log(date.toString());//Sun Feb 28 2016 13:40:36 GMT+0800 (中国标准时间)
6.valueOf()
valueOf方法返回对象的原始值,根据对象的不同,返回的可能是字符串、数值或boolean值等
var obj = { name: "obj" }; console.log(obj.valueOf());//Object {name: "obj"} var arr = [1]; console.log(arr.valueOf());//[1] var date = new Date(); console.log(date.valueOf());//1456638436303
如果我们自定义了valueOf方法,那么返回的值就是我们自己规定的值
function fn() {}
console.log(fn.valueOf()) //function fn() {}
fn.valueOf = function() { return 5; }
console.log(fn.valueOf()); // 5
关于toString()和valueOf(),这里还有一些东西需要注意,看?
1)当我们没有重新定义toString与valueOf时,函数的隐式转换会调用默认的toString方法,它会将函数的定义内容作为字符串返回。
function fn() { return 20; } console.log(fn + 10); 输出结果是 function fn() { return 20; }10
2)而当我们主动定义了toString()/vauleOf()方法时,那么隐式转换的返回结果则由我们自己控制的了,而且如果toString()/vauleOf()方法被重新定义了,输出函数名的话,不会再得到函数题,而是得到我们自定义的toString()/vauleOf()的值,其中valueOf()会比toString()后执行,这么说可能有些模糊,直接看?
function fn() { return 20; } fn.toString = function() { return 10; } console.log(fn + 10); // 20
function fn() { return 20; } fn.toString = function() { return 10; } fn.valueOf = function() { return 5; } console.log(fn + 10); // 15