面向对象常用的一些属性和方法

hasOwnProperty():看是不是对象自身(自己有别人没有)下面的属性。

hasOwnProperty()

1
2
3
4
5
var arr = [];
arr.num = 10;
Array.prototype.num2 = 20;
console.log(arr.hasOwnProperty("num")); //true 说明num属性只属于arr对象,其他对对象没有
console.log(arr.hasOwnProperty("num2")); //false 说明num2属性不是arr独享的

constructor:查看对象的构造函数

  • 每个原型都会自动添加constructor属性
  • for in 的时候有些属性是找到不到的
  • 避免修改constructor属性
1
2
3
4
5
6
7
8
9
10
11
12
function A (){
}
var a = new A();
console.log(a.constructor);
//结果是:function A(){
}
var arr = [];
console.log(arr.constructor); //Array

我们可以利用这个属性来做判断

1
2
3
var arr = [];
//判断arr是不是数组
console.log(arr.constructor == Array); //true

再来看

1
2
3
4
5
function A(){
}
//当我们执行上一句时,程序会为我们自动添加
A.prototype.constructor = A; //这个是隐式的

我们来做个试验

1
2
3
4
5
6
7
function A(){
}
//我们手动来写一下
A.prototype.constructor = Array; //相当于覆盖了隐式的
var a = new A();
console.log(a.constructor); //Array
1
2
3
4
5
6
function A(){
}
var a = new A();
//顺着原型链往上找,找到了最外层
console.log(a.hasOwnProperty == Object.prototype.hasOwnProperty); //true

注意:A.prototype.constructor = A;是系统自动添加的,我们不要去改它,但是有些情况我们会不自觉地就给改了。

1
2
3
4
5
6
7
8
9
10
function A(){
}
A.prototype.name = "Jack";
A.prototype.age = 20;
var a = new A();
console.log(a.constructor);
//结果function A(){
}

下面我们将A.prototype.name = "Jack";A.prototype.age = 20;改写成JSON的形式

1
2
3
4
5
6
7
8
9
10
11
function A(){
}
//这样写你感觉好像没有什么问题
A.prototype = {
name:"Jack",
age:20
};
var a = new A();
//可以看出构造函数已经改变
console.log(a.constructor); //function Object() { [native code] }
1
2
3
4
A.prototype = {
name:"Jack",
age:20
}; //这样相当于把A.prototype改写了,那么a再去找构造函数的时候,就会找到json的构造函数,自然就是function Object() { [native code] }

那要怎么办呢?答案就是在使用json的时候,把constructor给修正过来

1
2
3
4
5
6
7
8
9
10
function A(){
}
A.prototype = {
constructor:A,
name:"Jack",
age:20
};
var a = new A();
console.log(a.constructor); //function A (){};

系统自带的属性不能被for in 循环到

1
2
3
4
5
function A(){}
for(var attr in A.prototype){
console.log(attr);
}
//什么都没有,那好,我们自己写一个试试
1
2
3
4
5
6
function A(){}
A.prototype.name = "Jack";
for(var attr in A.prototype){
console.log(attr);
}
//结果输出name; 好,我们再写一个
1
2
3
4
5
6
7
function A(){}
A.prototype.name = "Jack";
A.prototype.constructor = A;
for(var attr in A.prototype){
console.log(attr);
}
//结果还是只有一个name,说明系统自带属性用for in 遍历不到,即使自己写一遍也不行

instanceof:对象与构造函数在原型链上是否有关系

看例子

1
2
3
4
function A(){}
var a = new A();
console.log(a instanceof A); //true
console.log(a instanceof Object); //true

toString():系统对象下面都是自带的,自己写的对象都是通过原型链找Object下面的。

1
2
var arr = [];
console.log(arr.toString); //function toString() { [native code] }
1
2
3
function A(){}
var a = new A();
console.log(a.toString); //function toString() { [native code] }
1
2
3
4
//自定义对象
function A(){}
var a = new A();
console.log(a.toString == Object.prototype.toString); //true
1
2
3
//系统对象
var arr = [];
console.log(arr.toString == Object.prototype.toString); //false

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

1
2
3
var arr = [1,2,3];
console.log(typeof arr.toString()); //string
console.log(arr.toString()); //"1,2,3"

知道原理之后可以自己改写

1
2
3
4
5
6
var arr = [1,2,3];
//我们知道系统对象的toString方法在自己的包装对象原型里
Array.prototype.toString = function(){
return this.join("+");
};
console.log(arr.toString()); //"1+2+3"

我们还可以用toString()来进行进制的转换

1
2
3
var num = 255;
//转成16进制
console.log(num.toString(16)); //"ff"

利用toString()做类型的判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arr = [];
var num = 123;
var str = "";
var obj = {};
var date = new Date();
var reg = /^$/;
var v = null;
console.log(Object.prototype.toString.call(arr)); //[object Array]
console.log(Object.prototype.toString.call(num)); //[object Number]
console.log(Object.prototype.toString.call(str)); //[object String]
console.log(Object.prototype.toString.call(obj)); //[object Object]
console.log(Object.prototype.toString.call(date)); //[object Date]
console.log(Object.prototype.toString.call(reg)); //[object RegExp]
console.log(Object.prototype.toString.call(v)); //[object Null]

小结:如何判断一个对象是不是数组?

1
2
3
4
var arr = [];
console.log(arr.constructor == Array); //true
console.log(arr instanceof Array); //true
console.log(Object.prototype.toString.call(arr) == "[object Array]"); //true

扩展:

写一个函数,获得函数名

1
2
3
4
function getFnName(fn){
if(typeof fn != "function") return;
return fn.name || /function (.+)\(/.exec(fn+"")[1];
}

简化一下

1
2
3
4
5
6
function getFnName(fn){
return typeof fn !== "function"?
undefined:
fn.name ||
/function (.+)\(/.exec(fn)[1];
}
1
2
3
4
5
function Person(){
this.name = "Jack"
}
var p = new Person();
console.log(getFnName(p.constructor)); //Person

本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid/JavaScript/some-atributes-and-methods-comonly-used-in-object-oriented.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!