网站首页 » 前端开发 » JavaScript » JavaScript 中面向对象的属性和方法
上一篇:
下一篇:

JavaScript 中面向对象的属性和方法

JavaScript 中面向对象的属性和方法比如 hasOwnProperty、constructor ,虽然不是很常用,但是了解它们对于学习 JavaScript 还是有帮助的。下面我们就来看看这些属性和方法

hasOwnProperty()

hasOwnProperty:判断是否是对象自身下面的属性

var arr = [];
arr.Site = "云库网";
Array.prototype.siteDomain = "yunkus.com";
console.log(arr.hasOwnProperty("site")); // true
console.log(arr.hasOwnProperty("siteDomain")); // true

constructor

constructor:查看对象的构造函数

function Site(){

}
var s1 = new Site();
console.log(s1.constructor); // function Site(){}
var arr = [];
console.log(arr.constructor); // function Array() { [native code] }

基本于上面的例子,我们就可以通过 constructor 来作类型判断

var arr = [];
console.log(arr.constructor == Array); // true

当我们创建一个自定义的对象时,程序会自动的为我们添加 constructor 属性。

比如我们上面的一个例子:

function Site(){

}
// 此时程序就会自动创建
Site.prototype.constructor = Site; // 第个函数都会自动生成这个这个 constructor,

所以当我们创建一个对象实例时,就可以通过 constructor 找到 Site
但是如果在创建完 Site 后 手动的更改了Site.prototype.constructor 那么 constructor 最后的值就变为你手动更改的值:

function Site(){

}
// 手动更改 constructor
Site.prototype.constructor = Array; // function Array() { [native code] }

但手动设置 constructor 是不有什么必要的,一般情况下我们都不更改这个值。那这些个方法是从哪来的呢?在创建自定义对象的时候都没有给它添加?

在 JavaScript 中有一个东西叫做原型链,对象可以沿着这个原型链向上查找,比如我们调用了一个 s1.hasOwnProperty()方法,这个方法在我们创建的对象实例中是没有的,于是程序会沿着原型链往上找也就是这的才爸 Site 对象,很显示我们了没有给 Site 对象添加这个方法,于是又向上找,找到 Object 对象,而这个方法就是挂载在 Object 对象上的。于是 s1 就把这个方法从爷爷这里拿去用了。
我们可以验证一下上面的说法正确与否:

function Site(){

}
var s1 = new Site();
console.log(s1.hasOwnProperty == Object.prototype.hasOwnProperty); // true

当我们需要给原型 prototype 添加一些属性或者方法时,就需要注意了,此时添加的姿势一定要对,不然会出现一些不可预测的问题。

这个正确的姿势:

function Site(){

}
Site.prototype.siteName = "云库网";
Site.prototype.siteDomain = "yunkus.com";
var s1 = new Site();
console.log(s1.constructor); // function Site(){}

这个是不正确的姿势:

function Site(){

}
Site.prototype = {
siteName:"云库网",
siteDomain:"yunkus.com"
}
var s1 = new Site();
console.log(s1.constructor); // function Object() { [native code] }

所以在给 prototype 添加属性或者方法时就得注意了,姿势一定要对。不对直接给 prototype 直接赋值比如像上面那个错误的姿势。但话又说回来,不怕万一就怕一万,万一我们不小心这样写子呢。还有救吗?其实还是有救的。我们可以手动修正这个 constructor

function Site(){

}
Site.prototype = {
constructor:Site,
siteName:"云库网",
siteDomain:"yunkus.com"
}
var s1 = new Site();
console.log(s1.constructor); // function Site(){}

虽然 constructor 和 property 是系统自动生成的,但是当我们用 for in 遍历时却遍历不到:

for(var arrt in Site.prototype){
    console.log(arrt);
} 
// 什么都没打印出来

当我们给手动给 prototype 添加属性时就可以遍历出来:

function Site(){

}
Site.prototype.name = "云库网";
Site.prototype.siteDomain = "yunkus.com";
for(var arrt in Site.prototype){
console.log(arrt);
}
// name siteDomain

所以请记住了,prototype 里的方法属性是不能用 for in 遍历出来的,而自定义的方法属性就可以通过forin 遍历出来。

但如果我手动写了一个 prototype.constructor 呢?会不会被遍历到?答案还是否定的:

function Site(){

}
Site.prototype.name = "云库网";
Site.prototype.siteDomain = "yunkus.com";
Site.prototype.constructor = Site;
for(var arrt in Site.prototype){
console.log(arrt);
}
// name siteDomain

toString()

toString():把对像转成字符串

首先必需要声明的一点就是:对于自定义的对象来说这个方法是来自 Object 对象的。而对于系统自带的方法比如 Array,这个方法是直接挂载到 Array 对象下的。

// 系统自带对象
var arr = [];
console.log(arr.toString == Object.prototype.toString); //false

// 自定义对象
function Site(){

}
var s1 = new Site();
console.log(s1.toString == Object.prototype.toString); // true

字符串转换

var arr = ["a","b","c"];
console.log(arr.toString());
console.log(typeof arr.toString()); // a,b,c

进制的转换

var num = 286;
console.log(num.toString(16)); // 11e
console.log(num.toString(8)); // 436
console.log(num.toString(2)); // 100011110

类型判断

var arr = [];
var num = 123;
var json = {name:"云库网",domain:"yunkus.com"};
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(num)); // [object Number]
console.log(Object.prototype.toString.call(json)); // [object Object]

所以我们作类型判断的时候就可以像下面这样写:

console.log(Object.prototype.toString.call(arr) == "[object Array]"); // true

那我们要选择哪一种方法来作类型的判断呢?一般情况下这三种方法我们都可以使用,但是有一种情况我们必需使用 Object.prototype.toString.call()方法。我们可以看看下面这个例子。

window.onload = function(){
    var ifm = document.createElement("iframe");
    document.body.appendChild(ifm);
    var ifmArray = window.frames[0].Array;
    var arr = new ifmArray;
    console.log(arr.constructor == Array); // false
    console.log(arr instanceof Array); // false
    console.log(Object.prototype.toString.call(arr) == "[object Array]"); // true
}

虽然这种场景在实践的应用中极少使用,但是也不能排除,所以推荐使用最后一种方法。如果你确定项目用不会使用到像上面的那种场景,那么这三种方法你可以随意使用。

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/javascript-object-oriented-programming-property-and-method/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论 END