您好,登錄后才能下訂單哦!
轉載請注明出處
原文連接 http://blog.huanghanlian.com/article/5b698ed6b8ea642ea9213f4c
對象中包含一系列屬性,這些屬性是無序的。每個屬性都有一個字符串key和對應的value。
概述
對象中包含一系列屬性,這些屬性是無序的。每個屬性都有一個字符串key和對應的value。
var obj = {x : 1, y : 2}; //定義obj對象, 有兩個屬性x和y
obj.x; // 1 //訪問對應obj.x屬性取到對應的值
obj.y; // 2 //訪問對應obj.y屬性取到對應的值
這里有兩個重點,一個是屬性是無序的,再一個每一個key
是字符串。
探索對象的key
var obj = {}; //定義對象obj
obj[1] = 1; //動態賦值數字1屬性值為1
obj['1'] = 2; //動態賦值字符串1屬性值為2
console.log(obj); // Object {1: 2} //實際上結果指向的是同一個屬性
//每個屬性都有一個字符串key和對應的value。
obj[{}] = true; //[{}] 空對象作為key
obj[{x : 1}] = true; //對象帶有屬性的對象作為key //js都會把它轉換成字符串然后再去處理,最終指向的是同一個屬性
console.log(obj)// Object {1: 2, [object Object]: true}
回顧-數據類型
函數,數組,日期,正則等都是對象
對象結構
var obj = {}; //字面量空對象 obj.y = 2; //賦值創建屬性x obj.x = 1; //賦值創建屬性y
對象有個特點,他的屬性可以動態的添加或刪除的
函數對象
function foo(){};
console.log(foo.prototype);
創建一個函數聲明
每一個函數都會有一個foo.prototype
對象屬性
function foo(){};
foo.prototype.z=1;
console.log(foo.prototype);
給foo.prototype
對象屬性添加屬性z
賦值為1,foo.prototype
對象屬性下有個constructor
屬性方法,該屬性其實是指向自己本身。
function foo(){};
foo.prototype.z=1;
console.log(foo.prototype);
var obj =new foo();
console.log(obj);
通過new
去實例化foo()
函數var obj =new foo();
那么這個obj
原型就會指向構造器的prototype
屬性也就是foo.prototype
,可以通過上圖看出打印輸出是一樣的。
對象創建-字面量
var obj1 = {x : 1, y : 2};
對象字面量 ,用{}設置屬性
var obj2 = { x : 1, y : 2, o : { z : 3, n : 4 } };
對象字面量也可以做一些嵌套,比如某些屬性值可以又是對象
創建對象-new/原型鏈
還有一種就是使用new
構造器的方法創建對象,先來了解javascript中的原型鏈。
什么是原型鏈
function foo(){} //定義函數對象
foo.prototype.z = 3; //函數對象默認帶foo.prototype對象屬性 對象添加z屬性=3
var obj =new foo(); //用構造器方式構造新的對象
obj.y = 2; //通過賦值添加2個屬性給obj
obj.x = 1; //通過new去構造這樣一個對象他的主要特點是,他的原型會指向構造器的foo.prototype屬性
obj.x; // 1 //訪問obj.x發現對象上有x返回1
obj.y; // 2 //訪問obj.y發現對象上有x返回2
obj.z; // 3 //obj上沒有z并不會停止查找,會去查找他的原型foo.prototype.z返回3
typeof obj.toString; // ‘function' 這是一個函數,toString是Object.prototype上面的每個對象都有
'z' in obj; // true obj.z是從foo.prototype繼承而來的,所以說obj里面有z
obj.hasOwnProperty('z'); // false 表示z并不是obj直接對象上的,而是對象原型鏈上的。
但是如果是賦值的話結果就一樣了。
比如我們賦值obj.z=5
如果給obj.z
嘗試去賦值,就不會像原型鏈上去查找了。先看obj.z
有沒有,有的話修改它的值,沒有的話,在對象上添加obj.z
。
obj.z = 5;
obj.hasOwnProperty('z'); // true
foo.prototype.z; // still 3
obj.z; // 5
obj.z = undefined;
obj.z; // undefined
那么怎樣能拿到原型鏈上的z呢
delete obj.z; // true 刪除對象上的z屬性
obj.z; // 3 //這樣就能獲取原型鏈上的z
對象創建-Object.create
從字面量理解是對象創建
Object.create({x:1});
是系統內置的函數,這個函數會接收一個參數,一般是一個對象。他會返回一個新創建的對象,并且讓這個對象的原型指向參數,參數一般是個對象。
var obj = Object.create({
x: 1
});
console.log(obj.x) // 1
console.log(typeof obj.toString) // "function"
console.log(obj.hasOwnProperty('x')); // false
console.dir(obj)
讀寫對象屬性
var obj = {
x: 1,
y: 2
};
console.log(obj.x); // 1
console.log(obj["y"]); // 2
obj["x"] = 3;
obj.y = 4;
創建對象字面量obj
,有x
和y
兩個屬性,可以用obj.y
(點)操作符去訪問他的屬性,也可以用obj["y"]
[中括號這里需要是字符串]
var obj = {
x1: 1,
x2: 2
};
var i = 1,
n = 2;
for (; i <= n; i++) {
console.log(obj['x' + i]);
}
// 輸出: 1, 2
obj['x']使用方法,obj['x']同等于obj.x。obj['x']可以在[]內拼接字符串,obj.x+""不是那么方便
var obj = {
x1: 1,
x2: 2
};
var p;
for (p in obj) {
console.log(obj[p]);
}
用for...in遍歷所有屬性
需要注意的是用for...in
去遍歷的話,有可能把原型鏈上的屬性也遍歷出來,并且他的順序是不確定的。
屬性讀寫-異常
var obj = {
x: 1
};//創建對象obj
console.log(obj.y); //如果訪問一個不存在的屬性會進行原型鏈查找如果找到末端還是找不到就會返回 undefined
var yz = obj.y.z; //不能獲取undefined的屬性z TypeError: Cannot read property 'z' of undefined
obj.y.z = 2; //不能給undefined的屬性z去賦值 TypeError: Cannot set property 'z' of undefined
var yz;
if (obj.y) {
yz = obj.y.z;
}//判斷當obj.y存在把他取出來
//巧用運算符
var yz = obj && obj.y && obj.y.z;
屬性刪除
var person = {
age: 28,
title: 'fe'
};
delete person.age; // true 表示刪除成功
delete person['title']; // true 表示刪除成功
person.age; // undefined
delete person.age; // true
delete Object.prototype; // false, 不允許刪除
//通過getOwnPropertyDescriptor方法去獲取一個屬性中所有的標簽,第一個參數是你要查看的對象,第二個是你要去檢測的屬性這樣就能拿到屬性的描述器
var descriptor = Object.getOwnPropertyDescriptor(Object, 'prototype');
console.log(descriptor);
屬性檢測
var cat = new Object; //使用new 構造對象
cat.legs = 4; //賦值屬性legs值為4
cat.name = "Kitty"; //賦值屬性name值為Kitty
'legs' in cat; // true 表示cat中有legs屬性 in操作符是會向原型鏈上查找的
'abc' in cat; // false 表示cat中沒有abc屬性
"toString" in cat; // true, 繼承 property有toString屬性
cat.hasOwnProperty('legs'); // true 表示cat直接量屬性有legs
cat.hasOwnProperty('toString'); // false 表示cat直接量屬性沒有toString toString是在原型有
cat.propertyIsEnumerable('legs'); // true legs可枚舉 查看是否可枚舉propertyIsEnumerable for...in會被循環
cat.propertyIsEnumerable('toString'); // false toString不可枚舉 查看是否可枚舉propertyIsEnumerable for...in不會被循環
自定義對象屬性,讓他的枚舉標簽是false
var cat = new Object; //使用new 構造對象
cat.legs = 4; //賦值屬性legs值為4
cat.name = "Kitty"; //賦值屬性name值為Kitty
'legs' in cat; // true 表示cat中有legs屬性 in操作符是會向原型鏈上查找的
'abc' in cat; // false 表示cat中沒有abc屬性
"toString" in cat; // true, 繼承 property有toString屬性
cat.hasOwnProperty('legs'); // true 表示cat直接量屬性有legs
cat.hasOwnProperty('toString'); // false 表示cat直接量屬性沒有toString toString是在原型有
cat.propertyIsEnumerable('legs'); // true legs可枚舉 查看是否可枚舉propertyIsEnumerable for...in會被循環
cat.propertyIsEnumerable('toString'); // false toString不可枚舉 查看是否可枚舉propertyIsEnumerable for...in不會被循環
//通過Object.defineProperty給cat目標對象去添加一個屬性price
//enumerable:是否能在for...in循環中遍歷出來或在Object.keys中列舉出來。
//value:屬性的值給屬性賦值
Object.defineProperty(cat, 'price', {enumerable: false, value: 1000});
cat.propertyIsEnumerable('price'); // false price不可枚舉 查看是否可枚舉propertyIsEnumerable for...in不會被循環
cat.hasOwnProperty('price'); // true 表示cat直接量屬性有price
console.log(cat)
for(var k in cat){
console.log(cat[k]);//循環出來看看能不能被枚舉
}
判斷對象屬性是否存在進行操作
if (cat && cat.legs) {
cat.legs *= 2;
}//8
判斷cat
是否存在且cat.legs
不是undefined
的時候,讓cat.legs
值乘等于2,表示cat.legs
乘以2再賦值給cat.legs
if (cat.legs !== undefined) {
// only if cat.legs is not undefined
}
判斷cat.legs
不等于undefined
的時候去做動作
if (cat.legs !== undefined) {
// only if cat.legs is not undefined
}
判斷cat.legs
嚴格不等于undefined
的時候去做動作
屬性枚舉
var o = {
x: 1,
y: 2,
z: 3
};
'toString' in o; // true
o.propertyIsEnumerable('toString'); // false
var key;
for (key in o) {
console.log(key); // x, y, z
}
這樣寫出來的對象原型鏈屬性默認是不可枚舉的,所以for....in
的時候原型鏈不會出來。
var o = {
x: 1,
y: 2,
z: 3
};
var obj = Object.create(o); //創建obj對象以o對象作為原型
obj.a = 4;
console.log(obj)
var key;
for (key in obj) {
console.log(key); // a, x, y, z
}
創建obj
對象以o
對象作為原型
所有對象上的屬性,和原型上的屬性都會遍歷中顯示出來
那有時候我只想處理對象上的屬性,不想遍歷我對象原型鏈上的屬性。
我們需要在加一個obj.hasOwnProperty(key)
的判斷,來過濾掉原型鏈上的屬性就可以了。
var o = {
x: 1,
y: 2,
z: 3
};
var obj = Object.create(o); //創建obj對象以o對象作為原型
obj.a = 4;
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)){
console.log(key); // a
}
}
JavaScript get/set方法
var man = {
name: 'huang',
weibo: '@.com',
get age() {
return new Date().getFullYear() - 1993;
},
set age(val) {
console.log('年齡不能設置' + val);
}
}
console.log(man.age); //23
man.age = 100; //年齡不能設置100
console.log(man.age); //23
定義了一個對象man
有屬性name
值是huang
,這里定義了一對get
和set
方法,來去訪問屬性age
語法
用get
或set
關鍵字開頭,空格,然后是屬性的名字,然后是括號再方括號,里面是一個函數體,
get
方法會返回當前日期的年份減去我的出生日,會拿到我的年齡。
set
方法會拿到括號賦值的值,唯一的參數創進來。
當訪問console.log(man.age); //23
會返回get
方法,
當使用man.age = 100;
也就是說給set
去賦值的時候,就會去調用set
方法,就會輸出年齡不能設置100
再去輸出console.log(man.age); //23
會發現仍然是23,因為set
沒做任何的事情。
var man = {
name: 'huang',
$age: null,
get age() {
if (this.$age == undefined) {
return new Date().getFullYear() - 1993;
} else {
return this.$age;
}
},
set age(val) {
val = +val;
if (!isNaN(val) && val > 0 && val < 150) {
this.$age = +val;
} else {
throw new Error('Incorrect=' + val);
}
}
}
console.log(man.age); //23
man.age = 100;
console.log(man.age); //100
man.age = 'abn';
console.log(man.age);//Uncaught Error: Incorrect=NaN(…)
get/set與原型鏈
function foo() {};
Object.defineProperty(foo.prototype, 'z', {
get: function() {
return 1;
}
});
var obj = new foo();
console.log(obj.z); //1
obj.z = 10;
console.log(obj.z); //還是輸出1
Object.defineProperty(obj, 'z', {
value: 100,
configurable: true
});
console.log(obj.z);//100
delete obj.z;
console.log(obj.z);//1
解釋
function foo() {};
創建一個foo函數
,就會有一個foo.prototype
Object.defineProperty(foo.prototype, 'z', {
get: function() {
return 1;
}
});
通過defineProperty
用git
方法來創建z屬性
,git
方法只是固定的返回1。
var obj = new foo();
使用new
方式來創建一個新的對象obj
,這樣這個obj
對象的原型會指向foo.prototype
console.log(obj.z); //1
當我們去訪問obj.z
的時候obj
對象上沒有z直接量屬性
,所以他會向上去查找,foo.prototype
原型,發現有一個z屬性
用的是get
方法,這樣就能返回1,
obj.z = 10;
console.log(obj.z); //還是輸出1
那么我賦值,嘗試給z
賦值為10,如果z不是用get方式賦值的是通過foo.prototype.z
原型賦值的話,再使用直接量去賦值是可以成功的,值會返回到obj
這個對象上,但是在這里賦值并沒有成功。仍然返回1。
這是因為當obj
對象上沒有z直接量屬性的時候,并且他的原型鏈查找發現有get
和set
方法的時候,那么當我們嘗試去賦值的時候,實際上會走原型上get
和set
方法的,而不會再去通過給當前對象obj
添加新屬性。
Object.defineProperty(obj, 'z', {
value: 100,
configurable: true
});
通過Object.defineProperty
給obj
目標對象去添加一個屬性z
console.log(obj.z);//100
這個時候obj.z是obj
的直接量返回100
delete obj.z;
由于configurable: true
所以刪除是成功的
console.log(obj.z);//1
這里因為直接量z被刪除們說以他會繼續去向上查找z
的get
方法。
小案例
var o={z:2};
Object.defineProperty(o,'x',{value:1});//默認writable=false只讀,configurable=false不可寫
o.z=6;
o.x=6;
console.log(o);
案例解釋
var o={};
Object.defineProperty(o,'x',{value:1});//默認writable=false只讀,configurable=false不可寫
var obj=Object.create(o);//創建obj對象以o對象作為原型
console.log(obj.x);//1 會向上查找返回原型鏈x屬性值1
obj.x=200; //嘗試去賦值200
console.log(obj.x);//賦值后打印任然是1
//那么如何去在obj對象添加x屬性呢?
//還是要用Object.defineProperty
//給obj對象添加一個自己的屬性x,這樣就可以覆蓋掉原型鏈上的不可寫的x,writable:true,configurable:true,value:100
Object.defineProperty(obj,'x',{writable:true,configurable:true,value:100});
console.log(obj.x);//100 obj.x是直接量屬性
obj.x=500; //直接量屬性可以賦值
console.log(obj.x);//500 //修改成功
屬性標簽
怎樣去看某一個對象上的屬性上都有哪些標簽
console.log(Object.getOwnPropertyDescriptor({pro:true}, 'pro'));檢查一個字面量的對象,添加屬性`pro:true`看字面量下的屬性`pro`的屬性標簽
//configurable:true,enumerable:true,value:true,writable:true
console.log(Object.getOwnPropertyDescriptor({pro:true}, 'a'));//去查一個根本不存在的屬性返回undefined
//undefined
通過Object.getOwnPropertyDescriptor(參數1,"參數2")
方法可以返回一個對象,這個對象上會顯示 當前這個屬性下所有的標簽,這個函數會接收兩個參數,第一個是你要去判斷的對象,第二個是一個字符串的屬性名,
console.log(Object.getOwnPropertyDescriptor({pro:true}, 'pro'));檢查一個字面量的對象,添加屬性`pro:true`看字面量下的屬性`pro`的屬性標簽
得到的結果是
//configurable:true,enumerable:true,value:true,writable:true
那么怎么去設置或者說設置對象的屬性標簽呢?
var person = {};
Object.defineProperty(person, 'name', {
configurable: false,
writable: false,
enumerable: false,
value: "繼小鵬"
});
console.log(person.name); //繼小鵬
person.price = 100; //修改不了
console.log(person.name); //還是繼小鵬
console.log(delete person.name); //false 不可刪除
解釋例子
創建一個空對象
var person = {};
通過Object.defineProperty(參數1,"參數2",{參數1})
第一個參數是要添加屬性的對象,第二個參數是一個字符串屬性的名字,第三個參數是一個對象,這個對象里面就是具體每一個標簽的值,
Object.defineProperty(person, 'name', {
configurable: false,//不可刪除
writable: false,//屬性的值就不能被重寫。
enumerable: true,//可枚舉
value: "繼小鵬"http://屬性的值給屬性賦值
});
結果符合預期
console.log(person.name); //繼小鵬
person.price = 100; //修改不了
console.log(person.name); //還是繼小鵬
console.log(delete person.name); //false 不可刪除
創建新的屬性使用Object.keys
var person = {};
Object.defineProperty(person, 'name', {
configurable: false,
writable: false,
enumerable: true,
value: "繼小鵬"
});
Object.defineProperty(person, 'type', {
configurable: true,
writable: true,
enumerable: false,
value: "繼小鵬222"
});
console.log(person);
console.log(Object.keys(person));
新創建的屬性enumerable: false,
不可枚舉,可以通過Object.keys(person)
的方法來去獲取對象上所有的key
因為新創建的屬性enumerable: false,
不可枚舉所有不可見。
使用Object.defineProperties()定義多個對象屬性標簽
Object.defineProperties(person, {
title: {
value: 'fe',
enumerable: true,
},
corp: {
value: 'SDF',
enumerable: true,
},
salary: {
value: '50000',
enumerable: true,
writable: true
}
});
console.log(person);
console.log(Object.getOwnPropertyDescriptor(person, 'corp'));
console.log(Object.getOwnPropertyDescriptor(person, 'salary'));
Object.defineProperties()
這個函數接收兩個參數,第一個參數是你要定義屬性的對象,第二個參數是一個對象,對象里包含屬性值列表集。
例子
var person = {};
Object.defineProperties(person, {
title: {
value: 'fe',
enumerable: true,
},
corp: {
value: 'SDF',
enumerable: true,
},
salary: {
value: '50000',
enumerable: true,
writable: true
},
luck: {
get: function() {
return Math.random() > 0.5 ? 'good' : 'bad';
}
},
promote: {
set: function(level) {
this.salary *= 1 + level * 0.1;
}
}
});
console.log(Object.getOwnPropertyDescriptor(person, 'salary'));
console.log(Object.getOwnPropertyDescriptor(person, 'corp'));
console.log(person.salary);
person.promote = 3;
console.log(person.salary);
console.log(person.luck);
對象標簽
對象級別也是有標簽的,主要有三種
[[proto]]
[[class]]
原型標簽
__proto__
__proto__
實際上就是原型,比如說當我們用new
構造器的方式去實例化函數對象,那么這個實例化對象的原型鏈會指向構造器的prototype
,一般的對象也會有原型,指向 Object.prototype
然后在往上就是nall
。
class標簽
var toString = Object.prototype.toString;
function getType(o) {
return toString.call(o).slice(8, -1);
};
console.log(toString.call(null)); //[object Null]
console.log(getType(null)); //Null
console.log(getType(undefined)); //Undefined
console.log(getType(1)); //Number
console.log(getType(new Number(1))); //Number
console.log(typeof new Number(1)); //object
console.log(getType(true)); //Boolean
console.log(getType(new Boolean(true))); //Boolean
class標簽是沒有一個直接的方式去查看他或者是修改他,可以間接的通過Object.prototype.toString;
的方式來去獲取class,
var toString = Object.prototype.toString;
先把Object.prototype.toString;
這樣一個函數拿到,賦值給toString
這樣方便后面代碼簡短一些,
function getType(o) {
return toString.call(o).slice(8, -1);
};
定義一個方法,返回toString.call(o)
來調用這個函數方法,并且把參數o
作為this
傳進去,然后用slice(8, -1);
表示是截取從第八個字符開始,一直到最后。
調用getType(1); //Number
getType(1)方法會返回類型。
extensible標簽
extensible標簽表示你這個對象是否可擴展,言外之意就是說對象上的屬性是否可以被繼續添加。
var obj={x:1,y:2};//創建對象
Object.isExtensible(obj);//true
創建對象obj,通過Object.isExtensible(obj);
來判斷對象是否可擴展,一般情況下默認返回true。表示可以擴展。
那么怎么樣不讓他擴展,不可修改不可刪除凍結對象
var obj={x:1,y:2};//創建對象
Object.isExtensible(obj);//true obj對象可擴展
Object.preventExtensions(obj); //設置obj對象不可擴展
Object.isExtensible(obj);//false obj對象不可擴展
obj.d=2; //嘗試給obj添加新的屬性會發現添加失敗
console.log(obj.d);//undefined
//如果已經組織對象可擴展,那么對象上的屬性標簽是否會發生變化呢?
console.log(Object.getOwnPropertyDescriptor(obj, 'x'));
//value: 1, writable: true, enumerable: true, configurable: true
//雖然我們阻止了對象不可添加新屬性,但是已有熟悉仍然可以修改和刪除,也是可以枚舉的。
//可以通過
Object.seal(obj);//會把對象上的屬性的configurable設置為false不可刪除
console.log(Object.getOwnPropertyDescriptor(obj, 'x'));
//value: 1, writable: true, enumerable: true, configurable: false
console.log(Object.isSealed(obj));//true 判斷對象是否被隱藏不可刪除
Object.freeze(obj);//讓對象凍結不可寫
console.log(Object.getOwnPropertyDescriptor(obj, 'x'));
//value: 1, writable: false, enumerable: true, configurable: false
console.log(Object.isFrozen(obj));//true 判斷對象是否被不可寫
序列化
var obj = {
x: 1,
y: true,
z: [1, 2, 3],
nullval: null
};
console.log(obj);
console.log(JSON.stringify(obj)); //{"x":1,"y":true,"z":[1,2,3],"nullval":null}
var obj1 = {
val: undefined,
a: NaN,
b: Infinity,
c: Date()
};
console.log(obj1);
console.log(JSON.stringify(obj1)); //{"a":null,"b":null,"c":"Fri Dec 16 2016 22:25:04 GMT+0800 (中國標準時間)"}
var obj2 = JSON.parse('{"x":1}');
console.log(obj2); //Object {x: 1}
console.log(obj2.x); //1
定義obj 字面量對象,有一些屬性,通過JSON.stringify(obj));
方法返回一個字符串{"x":1,"y":true,"z":[1,2,3],"nullval":null}
返回的字符串就是這個對象的序列化的結果。
需要注意一點這個序列化是有一些坑的,如果你的屬性值是undefined
的話,那么就不會出現在序列化的結果當中。
如果后端返回一個JSON數據我們怎么把他轉換成js對象呢?
使用JSON.parse('{"x":1}');
方法,需要注意的是合法的json屬性必須以雙引號引起來。
序列化-自定義
var obj = {
x: 1,
y: 2,
o: {
o1: 1,
o2: 2,
toJSON: function() {
return this.o1 + this.o2;
}
}
};
console.log(JSON.stringify(obj)); //{"x":1,"y":2,"o":3}
obj對象下有個屬性o他的值是一個對象,那么這個對象序列化的結果我可能想要自定義,那么我們只需要在這個當前的層級下寫一個toJSON
他的值是一個函數,toJSON
是固定這個key一定要這樣寫,然后這個函數會返回return this.o1 + this.o2;
這個this會指向當前層級的數也就是o,
這時候去JSON.stringify(obj));
的時候,這里面的o通過toJSON
這樣一個方法來去返回的。
其他對象方法
var obj = { //定義對象obj x: 1, y: 2 }; obj.toString(); //"[object Object]" 調用對象的toString方法會返回"[object Object]"這樣的字符串實際上沒有太大意義
//定義自己對象上個的toString方法
obj.toString = function() {
return this.x + this.y; //返回對象的x和y相加作為結果
}
"Result" + obj; //"Result3" 左邊是字符串這樣會理解為字符串拼接那么他就會調用obj.toString所以返回結果"Result3"
//valueOf是嘗試把對象轉換為基本類型的時候會自動去調用的一個函數,這里自定義返回值
obj.valueOf = function() {
return this.x + this.y + 100;
} + obj; //103 再去用一員加號操作符把他轉換為數字這次返回的結果是103是從這個valueOf而來的
"Result" + obj; //"Result103"
需要主要的是這里面valueOf和toString都存在的時候那么不管是一元的加號還是2元的字符串拼接在做具體操作時,都會嘗試把對象轉換為基本類型,那么他會先去找valueOf。如果valueOf返回的是基本類型那么就以valueOf的值作為結果反之如果valueOf不存在或者返回的是對象,那么就會去找toString。如果valueOf和toString都沒有或者都返回的對象,那么就會報錯。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。