,什么是js对象
对象是javaScript的数据类型。对象是一种复合值。他将很多值聚合在一起,可以通过名字访问这些值。对象可以看做对象的无序集合,每一个属性都是一个 名/值 对 ,属性名是字符串,因此我们可以看成字符串到值的映射。
对象不仅仅是字符串到值的映射,除了可以保持自有属性,javaScript对象还可以从一个成为原型的对象继承属性。对象的方法通常是继承的属性
js对象是动态的----可以新增删除属性
对象是可变的,我们通过引用来操作对象。如果一个变量x是指向一个对象的引用,那么执行代码let y=x;变量y也指向同一个对象引用。通过变量y修改这个对象也会对变量x造成影响
对象常用的用法是创建(create),设置(set), 查找(query),删除(delete).检测(test)和枚举(enumerate)它的属性。
属性包括名字和值,对象中不能存在两个同名的属性,属性名可以是任意字符串,值可以是任意js值,或者可以是一个getter或setter函数。除了名字和值之外,每个属性还有一些与之相关的值,成为‘属性特性’
◆可写(writable attribute) ,表明是否可以设置该属性的值
◆可枚举(enumerable attribute),表明是否可以用for/in循环返回该属性
◆可配置 (configurable attribute),表明是否可以删除修改该属性
除了属性之外,每个对象还拥有三个相关的对象特性
◆对象的原型(prototype)指向另一个对象,本对象的属性继承来自它的原型对象
◆对象的类 (class),是一哥标识对象类型的字符串
◆对象的扩展标记指明了是否可以向该对象添加属性
最后我们用下面的术语来对三类js对象和两类属性作区分
◆ 内置对象是由es规范定义的对象或类,比如数组,函数,日期,正则表达式..
◆宿主对象指的是浏览器对象
◆自定义对象是由运行中的js代码创建的对象
◆自有属性 直接在对象中定义的属性
◆继承属性在对象的原型对象中定义的属性
1.创建对象
可以通过对象直接量,关键字new和Object.create()函数来创建对象
1.1 对象直接量
创建对象最简单的方法通过对象直接量。对象直接量由若干个名/值对组成的映射表,名/值对中间用冒号隔开,,名/值对之间用逗号隔开,整个映射表用花括号括起来。属性名可以是js标识符和可以是字符串直接量,属性的值可以是任意类型的js表达式。
eg:
let person={
title:'ssss',
time:'2022/4/5',
address:'地址',
getName:function(){
console.log(this.name)
}
};
注:对象直接量是一个表达式,这个表达式的每次运算都会创建并初始化一个新对象。每次计算对象直接量的时候,也都会计算它的每个属性值。也就是说,重复调用的函数中的循环体使用了对象直接量,它将会创建很多新的对象,并且每次创建对象的属性值也不同
1.2 通过new创建
new 运算符创建并初始化一个新的对象。关键字new后跟随一个函数的调用。这里的函数称作构造函数,构造函数用以初始化一个新创建的对象。js语言核心中的原始类型都包含内置函数 eg
new Object();//创建一个空对象 {}
new Array();//创建一个空数组
new Date();//创建一个当前日期的date对象
new RegExp();//创建一个可以进行模式匹配的EegExp
除了内置的构造函数,用自定义的构造函数来初始化新对象也是非常常见
1.3原型
什么是原型?
每一个js对象除了(null除外)都和另一个对象有关联。‘另一个对象’就是我们所熟知的原型,每一个对象都从原型中继承属性。
所有通过对象直接量创建的对象都具有一个原型对象,可以通过Object.prototype获取对对象原型的引用。通过关键字new和构造函数创建的对象的原型就行构造函数的prototype的属性值。因此,同使用{}创建对象一样,通过new Object() 创建的对象也继承自Object.prototype。同样通过new Array()创建的对象的原型是Array.prototype,通过new Date()创建的原型是 Date.Prototype
没有原型的对象为数不多 Object.prototype就是之一,它不继承任何属性。其他原型对象都是普通对象,普通对象都有原型。所有的内置构造函数以及自己定义的构造函数都具有一个继承自Object.prototype的原型,比如
let today=new Date();
today继承了Date.prototype , Date.prototype继承了Object.prototype。这一系列的原型对象就是所谓的原型链
1.4 Object.create()
Object.create()是一个静态函数,它用来创建一个新的对象,其中第一个参数是这个对象的原型。第二个可选参数,用以对对象的属性进行进一步描述。
◆使用它的方法很简单,只需要传入所需的原型对象即可
eg:
var o1=Object.create({x:1,y:2});
console.log(o1)
◆可以通过null创建一个没有原型的原型对象
let o2=Object.create(null);
console.log(o2)
◆如果想创建一个普通的空对象,需要传入Object.prototype
let o3=Object.create(Object.prototype);
console.log(o3)
可以通过任意原型创建新对象(换句话说,可以使用任意对象继承),当对象读取继承对象的属性时,实际上读取的是继承来的值,继承对象的赋值只会影响这个继承对象的自身,而不会影响原始对象,eg
Object.create(p)
let p = { x: 1, y: 2 };
var o1 = Object.create(p);
o1.x = 222
console.log('p:', p)
console.log('o1:', o1)
2属性的查询和设置
对象可以通过(.)或([])运算符来获取属性的值。运算符左侧应当是一个表达式,它返回的是一个对象。对于‘.’来说,右侧必须是一个以属性名称命名的简单表示符。对于方括号来说([]),方阔内必须是一个计算结果俄日字符串的表达式,这字符串就是属性的名字
let p = { x: 1, y: 2 };
console.log(p.x);//1
console.log(p['y']);//2
2.1 作为关联数组的对象
object.property和object['property']值相同
第一种语法使用了点运算符和一个标识符。第二种语法使用了方括号和一个字符串,看起来更像数组,只是这个数组元素是通过字符串索引而不是数字索引,使用[]访问属性数组元素必须是一个字符串
可以通过object.property=value或object.property=value 重新赋值属性的值
2.2 继承
对象具有‘自有属性’,也有一些属性时从原型对象继承而来的。为了更好的理解这种继承,必须更深入地了解属性访问细节 以下的例子为案例eg
要查询变量q的x属性,如何q不存在x,那么会在q的原型对象上找,q的原型对象没有x,那么就在q的原型对象的原型对象上找,知道x或者找到一个原型是null的对象为止。可以看到对象的原型属性形成一个链,通过这个链开实现属性的继承
let o={} ;//Object.prototype
o.x=1;
let p=Object.create(o);//继承了o 和Object.prototype
p.y=3;
let q=Object.create(p);//继承了p,o和Object.prototype
q.z=3;
let s=q.toString();//toString 继承了Object.prototype方法
console.log(s);
let sum= q.x+q.y;
console.log(sum);//4
现在假设给对象o的属性x赋值
●如果o中已经有x属性了(这个属性不是继承来的),那么这个赋值操作只改变这个已有属性x.
●如果o中不存在属性x,那么赋值操作给o添加一个新的属性x。如果之前o继承自有属性x,那么这个继承的属性就会被新创建的同名属性覆盖了。
属性赋值操作首先检查原型链,以此判断是否允许赋值操作。例如,如果o继承自一个只读属性x,那么操作赋值是不允许的。如果允许赋值操作,它也是在原始对象上创建属性或对已有属性赋值,而不会修改原型链。在js中,只有在查询属性时才体会到继承的存在,而设置属性跟继承无关,该特性让程序员有选择的覆盖继承属性
属性赋值要么失败,要么创建一个属性,要么在原始对象中设置属性。但有一个例外。如果o继承自属性x,而这个属性时一个具有setter方法的accessor属性,那么这时将调用setter方法而不是给o创新一个属性x。需要注意的是,setter方法是对象o调用的,而不是定义这个属性的原型对象调用的。因此如果setter方法定义的任何属性,这个操作只针对o本身,并且不会修改原型链
2.3属性访问错误
属性访问并不总是返回或设置一个值。
查找一个不存的属性并不会报错,如果在对象o自身的属性或继承的属性中均未找到属性x,属性访问表达式o.x返回undefined
如果查找o.x,对象o不存在,会抛出一个类型错误异常
console.log(obj.x)
在这些场景下给对象o设置属性p会失败
● 假设o的属性p是只读的,不能给只读属性重新赋值(defineProperty()方法只有一个例外,可以对可配置的只读属性重新赋值)
● 假设o的属性p是继承属性,且它是只读的:不能通过同名的自有属性覆盖只读的继承属性
● o中不存在自有属性p:o中没有使用setter方法继承属性p,且o的可扩展性(extensible attribute)是false 。如果中不存在p,而且没有setter方法可供调用,则p一定添加至o中。但如果o不是可扩展的,那么在o中不能定义新属性
3 删除属性
delete运算符可以删除对象的属性。它的操作数应当是一个属性访问表达式。让人感到意外的是,delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性 ,
3.1 删除属性的两种方法
1.delete book.author
2.delete book['title']
● delete运算符只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型上删除它,而且这个会影响所有胡扯这个原型的对象)。
● delete表达式删除成功或没有任何副作用是(比如删除一个不存在的属性)时,他会返回一个true,如果delete后不是一个表达式,delete同样返回true
let o={x:1};
console.log( delete o.x);//true
console.log(delete o.x);//true
console.log(delete o.toString);//true
console.log(delete 1);//无意义,返回true
3.2 delete 不能删除那些可配置性为false的属性(尽管可以删除不可扩展对象的可配置性)。
● 某些对象的属性是不可配置的,比如变量声明和函数声明创建全局的对象属性。
● 在严格模式中,删除一个不可配置属性会报一个类型的错误
● 在非严格模式中,删除一个不可配置属性会报false
eg:
console.log(delete Object.prototype);//false
var x=1;
console.log(delete this.x);//false
function f(){
}
console.log(delete this.f);//false
● 在非严格模式中删除全局对象的可配置属性,可以省略对全局对象的引用,直接在delete操作符后跟要删除的属性名即可
this.x=1;//创建一个可配置的全局属性(不能用var)
delete x;//将它删除
●在严格模式中,delete后跟随一个非法的操作数,则会报一个语法错误,因此必须显示指定对象及其属性
delete x;//严格模式下报语法错误
delete this.x;//正常工作
4检测属性
js对象可以看做属性的集合,我们经常会检测集合中的成员的所属关系。判断某个属性是否存在于某个对象中。可以是in操作符。hasOwnPrepetry()和propertyIsEnumerable()方法来完成这个工作,也可以用属性查询的方式检测到
4.1 in操作符
in操作符左侧是属性名(字符串)。如果对象的自有属性或继承属性中有这个属性则会返回true
let o={x:1};
console.log("x" in o);//true o是x的属性
console.log("y" in o);//fasle y不是o的属性
console.log('toString' in o)//true toString是o继承来的属性
4.2 hasOwnProperty
hasOwnProperty 用来检测给定的名字是否是对象自有属性。如果是返回true,如果不是返回ture。
对于继承属性它将返回false
let o={x:1};
console.log(o.hasOwnProperty("x"));//true x是o的自有属性
console.log(o.hasOwnProperty('y'));//false y不是o的属性
console.log(o.hasOwnProperty('toString'));//falsetoString的属性数继承来的,不是自有属性
4.3 propertyIsEnumerable
propertyIsEnumerable方法是hasOwnProperty的增强版,只有检测到是自有属性,且这个属性是可枚举的才返回true,否则返回false
let o={x:1};
console.log(o.propertyIsEnumerable("x"));//true o有一个x属性且是枚举的
console.log(o.propertyIsEnumerable('y'));//false o没有y的属性
console.log(o.propertyIsEnumerable('toString'));//false toString的属性数继承来的,不是自有属性且不是枚举的
6.4.4 还可以用!==的方法判断一个属性是否是undefined”
注:检测属性需要用!==而不是!=。是因为!== 可以区分undefined和null
let o={x:1};
console.log(o.x !== undefined);//true o中有x属性
console.log(o.toString !== undefined);//true o继承了toString属性
5枚举属性
我们可以通过for --- in 循环遍历对象,for/in循环可以在循环体中遍历对象中所有的可枚举属性(包括自由属性和继承属性),把属性名赋值给循环变量。对象继承内置的方法是不可枚举的
eg:
//只循环出了x,y,z 不会循环出toString
let o = { x: 1, y: 2, z: 3 };
o.propertyIsEnumerable('toString')//false
for (let p in o) {
console.log(p)
}
由于有些对象可枚举属性是自有属性和枚举属性,如果想过滤掉继承属性,可以用以下方法操作
let o = { x: 1, z: function () { } };
let o1 = Object.create(o);
o1.y = 3;
o1.h = function () { };
for (let p in o1) {
if (!o1.hasOwnProperty(p)) {
continue;
}
console.log(p)
}
写一个函数,合并两个对象的属性,且有同名的属性,后一个属性可以覆盖到前一个属性
let obj1={x:1,y:2,z:33,arr:[{x:222}]};
let obj2={x:111,k:333,l:334,z:'ppp',arr:[1,24,5]}
function mergeObj(o,p){
for(let prop in p){
o[prop]=p[prop]
}
return o;
}
console.log(mergeObj(obj1,obj2));//{"x":111,"y":2,"z":"ppp","arr":[1,24,5],"k":333,"l":334}
返回一个数组,这个数组包含o中可枚举的自有属性的名字
方案1
let o = { x: 1, z: function () { } };
let o1 = Object.create(o);
o1.y = 3;
o1.h = function () { };
function getOwnArray(obj) {
let arr = []
for (let prop in obj) {
if (o.hasOwnProperty(prop)) {
continue;
}
arr.push(prop)
}
return arr;
}
console.log(getOwnArray(o1));// ["y", "h"]
方案二
console.log(Object.keys(o1));// ["y", "h"]
6 属性getter和setter
我们知道,对象属性是由名字,值和一组特性(attribute)构成。在es5中,属性值可以用一个或两个方法替代,这两个方法就是setter和getter。有setter和getter定义的属性称做‘存取器属性’,它不属于数据属性,数据属性只有一个简单的值
当程序查询存储器属性时,js调用getter方法(无参数)。这个方法返回的值就是属性存储器属性的值。当程序设置一个存取器属性的值时,js调用setter方法,那么它只是一个只读属性。如果它只有setter方法,那么它只是一个可写属性(数据属性中有一些例外),读取只写属性总是返回undefined
定义存取七属性最简单的方法是使用对象直接量语法的一种扩展写法
存取器属性定义为一个或两个属性同名的函数,这个函数定义没有使用function关键字,而是使用get和set 。
注:这里没有使用冒号将属性名和函数体分隔开,但是在函数体的结束和下一个方法或数据属性之间有逗号分隔
适用场景:比如只能检测属性的写入值以及每次属性读取返回不同的值
let o={
x:1,
y:1,
get r(){
return this.x
},
set r(newValue){
this.x=newValue*2
}
}
o.r=3;
console.log(o.r);//6
和数据一样,存储器属性也是可以继承的
let o={
x:1,
y:1,
get r(){
return this.x
},
set r(newValue){
this.x=newValue*2
}
}
o.r=3;
console.log(o.r);//6
let q=Object.create(o);
q.r=10;
console.log(q.r);//20 继承了对象o的存取起属性
7属性的特性
除了包含名字和值之外,属性还包含一些标识它们可写,可枚举和可配置特性。
数据的属性包括值特性(value),可写性(writable), 可枚举性(enumerable)和可配置性(configurable)。
注:存储器属性不具有值特性(value)和可写性(writable),它们的可写性是由setter方法存在是否决定的。 因此存取起属性的是读(get), 写(set) ,可枚举,可配置
为了实现属性特性的查询和设置操作,es5定义了一个名为‘属性描述符’的对象,这个对象代表4个特性。描述对象的属性和他们所描述的特性是同名的,数据属性的描述对象的属性有value,writable, enumerable和configurable,其中writable, enumerable和configurable这三个值是布尔值
存取器属性的描述对象则用get属性和set属性代替value和writable
可以通过Object.getOwnPropertyDescriptor()这个方法可以获取某个对象特定的自有属性描述
eg:
let o={
x:1,
get r(){
return this.x * this.x;
}
}
console.log(Object.getOwnPropertyDescriptor(o,'x'));//{value: 1, writable: true, enumerable: true, configurable: true}
//{set: undefined, enumerable: true, configurable: true, get: ƒ}
console.log(Object.getOwnPropertyDescriptor(o,"r"));
console.log(Object.getOwnPropertyDescriptor(o,"toString"));//undefined 因为这个是继承属性,所有不会返回
Object.getOwnPropertyDescriptor()这个方法只能得到自有属性的描述。要想获取继承属性的特性,需要遍历原型链 Object.getPrototypeOf()。
要想设置属性的特性,或者想让新创建属性具有某种特性 ,则需要调用Object.definedPeoperty(),传入要修改的对象,要创建或修改的属性的名称以及属性描述对象,这个方法么修改属性,那么新创建属性,但是不能修改继承属性
eg:
let o={};
Object.defineProperty(o,'x',{
value:1,
writable:true,
enumerable:false,
configurable:true
})
//属性存在但是是不可枚举的
console.log(o.x);//1
Object.keys(o);//[]
//现在对属性x做修改,让它变只读
Object.defineProperty(o,'x',{
writable:false,
})
o.x=22;//操作失败,但是不会报错,在严格模式中会报错
console.log(o.x);//1
//属性依然是可配置的,因此可以通过这种方法来修改
Object.defineProperty(o,"x",{
value:2
})
console.log(o.x);//2
//现在将x属性改成存取器属性
Object.defineProperty(o,"x",{
get:function(){
return 0
}
})
console.log(o.x)//0
defineProperties()创建多个属性,创建方法如下
let p=Object.defineProperties({}, {
x:{
value:1,
writable: true,
enumerable: true,
configurable: true
},
y:{
value:1,
writable: true,
enumerable: true,
configurable: true
},
r:{
get:function(){
return this.x+this.y;
},
set:function(newValue){
console.log(newValue);//2
},
enumerable: true,
configurable: true
}
})
p.r=p.x+p.y;
console.log(p.r)//r
对于那些不允许创建或修改的属性来说,用Object.definedPeoperty和defineProperties修改和新建就会抛出类型错误。可配置属性控制这其他属性(包括属性是否删除)的修改,如果属性是不可配置的,仍然可以将可写属性改为不可写属性。下面是完整规则。任何对Object.defineProperty和Object.defineProperties违反规则的使用都会抛出类型错误异常
●如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给他添加任何新属性
●如果属性是不可配置的,则不能修改它的可配置性和可枚举性
●如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转为数据属性
●如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true改为false
●如果属性是不可配置不可写的,则不能修改它的值
对象操作案例,把对象obj2的属性特性复制到对象obj1里,如果obj2和obj1同样的属性,obj1的属性不变,
function mergeObj(obj1, obj2) {
let arr = Object.getOwnPropertyNames(obj2);
for (var i = 0; i < arr.length; i++) {
if(arr[i] in obj1){
continue;
}
console.log(i)
let des = Object.getOwnPropertyDescriptor(obj2,arr[i]);
console.log(des)
Object.defineProperty(obj1, arr[i], des);
}
return obj1;
}
console.log(mergeObj(o, p))
对象操作案例,把obj2的属性特性到obj1里,如果obj2和obj1同样的属性,还有obj2属性覆盖到obj1的属性
let p = Object.defineProperties({}, {
x: {
value: 1,
writable: true,
enumerable: true,
configurable: true
},
y: {
value: 1,
writable: true,
enumerable: true,
configurable: true
},
z:{
value: 333,
writable: true,
enumerable: true,
configurable: true
},
r: {
get: function () {
return this.x + this.y;
},
set: function (newValue) {
console.log(newValue);//2
},
enumerable: true,
configurable: true
},
})
p.r = p.x + p.y;
console.log(p)//r
let o={
x:3,
y:555,
get r(){
return this.x
}
}
function mergeObj(obj1, obj2) {
let arr = Object.getOwnPropertyNames(obj2);
for (var i = 0; i < arr.length; i++) {
console.log(i)
let des = Object.getOwnPropertyDescriptor(obj2,arr[i]);
console.log(des)
Object.defineProperty(obj1, arr[i], des);
}
return obj1;
}
console.log(mergeObj(o, p))
8.对象的3个属性
每一个对象都有与之相关的原型(prototype),类 (class)和可扩展性(extensible attribute)
8.1原型属性
对象的原型属性是用来继承属性的,这个属性如此重要,以至于我们经常把‘o的原型属性’直接叫做o的原型
原型属性是在实例对象创建好之前设置的,通过对象直接量创建的对象使用的是Object.prototype作为它们的原型。通过new创建的对象是使用构造函数的prototype属性作为他们的原型 ,通过Object.create()创建对象使用的一个参数作为它们的原型,也可以是null
查询原型链的方法
● Object.getPrototypeOf查找原型
let p={x:1}
let o=Object.create(p);
console.log(Object.getPrototypeOf(o) == p);//true
console.log(Object.getPrototypeOf(p) == Object);//true
● 也可以用o.constructor.prototype 检测一个原型对象。通过new创建的构造函数,通常会继承一个constructor,这个constructor指向这个构造函数,constructor.prototype 才是对象直接量的真正的原型,通过对象Object.create()不能用这个方法检测
let p={x:1}
console.log(p.constructor == Object)//true
console.log(p.__proto__== Object.prototype)//true
●通过对象Object.create(),要想检测一个对象是否另一个对象的原型isPrototypeOf()或
Object.getPrototypeOf()检测
let p={x:1}
let o=Object.create(p);
onsole.log(o.__proto__==p) //true
●可以通过__proto__直接查找对象的原型,既可以
let p={x:1}
let o=Object.create(p);
onsole.log(o.__proto__==p) //true
8.2 类属性
对象的类属性是一个字符串,用以表示对象的类型信息,要想获取对象的类,可以调用toString()方法,然后返回字符串的第8个倒数第二个位置直接的字符,因为很多继承方法的toString()方法重新写了,为了调用正确的toString()版本,必须间接调用Function.call()方法,如
注:通过直接量净和Object.create 创建的对象的类属性是 ‘Object’,那些自定义的构造函数的对象也是,类属性也是'Object'
function classof(o){
if(o === null){
return "Null";
}else if(o=== undefined){
return 'Undefined'
}
return Object.prototype.toString.call(o).slice(8,-1);
}
classof(null);//null
classof(1);//number
classof("");//String
classof(false);//Bollean
classof({});//Object
classof([]);//Array
classof(/./);//Regexp
classof(new Date());//Date
classof(window);//Window
function f(){
}
classof(new f());//Object
8.3可扩展性
对象的可扩展性用以表示是否可以给对象添加新属性,所有的内置对象和自定义对象都是可扩展的,宿主对象的可扩展性是由js引擎定义的,在es中,所有的内置对象和自定义对象是可扩展的,除非将它们转为可扩展的性的函数
可以通过Object.esExtensible()来判断对象是否扩展。如果想将对象转为不可扩展的则用
Object.preventExtensions(),
注:preventExtensions,一旦将对象转为不可扩展,就无法将其转为可扩展的,只影响本身的扩展性,如果给一个不可扩展的对象的原型添加一个属性,这个可扩展的对象同样会继承这些属性,
可扩展性的目的是将对象‘锁定’,以免外界的干扰。对象的可扩展性通常和属性的可配置性与可写性配合使用
Object.seal()除了将对象设置为不可扩展的,还可以将对象的所有属性设置为不可配置的。也就是说不能给这个对象添加新的方法,原有的自有属性不能删除或配置,但是可以对可写属性进行
值的设置
Object.freeze()将更严格的锁定对象----‘冻结’,除了将对象设置为不可扩展的和将其属性设置为不可配置的之外,还可以将它最有的所有数据属性设置为只读。存取器属性除外。使用Object.isFrozen()来检测对象是否冻结
9.序列化对象
对象序列化是指将对象的状态转换为字符串,也可以将对象还原为函数。 JSON.stringity()和JSON.parse()用来序列化和还原js对象
注:
NaN,infinity和-infinity序列化的结果是null,
日期系列化的结果是ISO格式的日期字符串,跟Date.toJSON一样,但JSON.parse()仍然保留它的字符串传统,而不会将它们还原
JSON.stringity()只能序列化对象的自有属性
JSON.stringity()和JSON.parse()都可以接收第二个可选参数,通过传入需要序列化或还原的属性来定制自定义的序列化或还原操作
10 对象方法
所有的js对象都从Object.prototype继承属性。这些继承属性主要是方法,因为js程序员对继承方法更感兴趣,我们已经讨论过hasOwnProperty(),propertyIsEnumerable(),和isPrototypeOf()这三个方法,以及Object函数定义的静态函数Object.create,Object.getProtypeOf()....
10.1 toString()
toString() 没有参数,它将返回一个表示调用这个方法的对象值的字符串。需要将对象转为字符串时,js才会调用这个方法,比如用‘+’连接一个字符串和对象时会使用 toString()
10.2 toLacaleString()
这个方法返回一个表示这个对象本地的字符串,它可以对数字,日期和时间做本地的转换
10.3 toJson
js会在调用JSON.stringify()使用toJSON方法
10.4valueOf()
js学院把对象转换为原始值而非字符串时用它,尤其转为数字的时候。如果需要在原始值的上下文使用了对象,会调用它
网友评论