你不知道的js-对象

lu0511 lu0511     2022-10-08     283

关键词:

1、对象有两种形式定义:声明文字形式和构造形式。

2、内置对象:js中有一些对象子类型,称为内置对象

var strprimitive = ‘I am string‘;
typeof strprimitive;//‘string‘
strprimitive instanceof String; //false

var strobj = new String(‘I am string‘);
typeof strobj;
strobj instanceof String;

Object.prototype.toString.call(strobj); // [object string]

 typeof ,instanceof,Object.prototype.toString.call()区分对象类型

js中通过Object.prototype.toString方法----精确判断对象的类型

1、在 JavaScript 里使用 typeof 来判断数据类型,只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” 五种。

对于数组、函数、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。

2、instanceof判断对象类型,有点麻烦

//对象
(a instanceof Object) && !(a instanceof Array) && !(a instanceof Function)
//数组
(a instanceof Object) && (a instanceof Array)
//函数
(a instanceof Object) && (a instanceof Function)

3、使用Object.prototype.toString方法

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/d/));//[object RegExp]

所有类型都会得到不同的字符串,几乎完美。

 

那为什么不直接用obj.toString()呢?

这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。 

 4、内容

 

 var myObject = {
  a:2
 };
 myObject.a;//2
 myObject[‘a‘];//2

 

如果要访问myObject 中a位置上的值,我们需要使用.操作符,或者[]操作符

.a语法通常被称作属性访问,[‘a‘]语法通常被称为键访问

区别在于.操作符要求属性名满足标识符的命名规范,而[..]语法可以接受任意UTF-8/Unicode字符串作为属性名

由于[..]语法使用字符串来访问属性,所以可以在程序中构造字符串

在对象中属性名永远是字符串

5、可计算属性名

ES6增加了可计算属性名,可以在文字形式中使用[]包裹一个表达式当作属性名。

 var prefix = "foo";
 var myObject = {
  [prefix+"bar"]:‘hello‘,
  [prefix+"baz"]:‘world‘
 };
 myObject[‘foobar‘];//hello
 myObject[‘foobaz‘];//world

 6、数组

数组期望的是数值下标,也就是说值存储的位置是非负整数

数组也是对象,所以虽然每个下标都是整数,仍然可以给数组添加属性

 var myArray = [‘foo‘,42,‘bar‘];
 myArray.baz = ‘baz‘;
 myArray.length;//3
 myArray.baz;//‘baz‘

可以看到虽然添加了命名属性,数组的length值并没有发生变化

如果你试图向数组中添加一个属性但是属性名看起来很像一个数字,那它会变成一个数值下标

var myArray = [‘foo‘,42,‘bar‘];
myArray[‘3‘] = ‘baz‘;
myArray.length;//4
myArray[3];//‘baz‘

7、复制对象

对于JSON安全的对象来说,有一种巧妙的复制方法:

JSON安全:也就是说可以被序列化为一个JSON字符串并且可以根据这个字符串解析出一个结构和值完全一样的对象

var newObj = JSON.parse(JSON.stringfy(someObj));

这种方法需要保证对象是JSON安全的,所以只适用于部分情况

浅复制易懂,问题少一些。

Object.assign(..)第一个参数是目标对象,之后可以跟一个或多个源对象

8、属性描述符

从ES5开始,所有属性都具有了属性描述符

var myObject = {
  a:2
}
Object.getOwnPropertyDescriptor(myObject,‘a‘);

// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }

 可以使用Object.defineProperty()来添加一个新属性,或者修改一个已有属性

Object.defineProperty(myObject,‘a‘,{
    value: 2,
    writable: true,
    enumerable: true,
    configurable: true
});
myObject.a;//2

9、对象默认的[[Put]] 和[[Get]]操作分别可以控制属性值的设置和

在ES5中可以使用getter和setter部分改写默认操作,但是只能应用在单个属性上,无法应用在整个对象上。getter是一个隐藏函数,会在获取属性值时调用,setter也是一个隐藏函数,会在设置属性时调用。

var myObject = {
  get a() {
    return 2;
  }
};
myObject.a = 3;
myObject.a;//2

由于我们只定义了a的getter,所以对a的值进行设置时,set操作会忽略赋值操作,不会抛出错误。

即使有了合法的setter我们定义的getter只会返回2。所以set操作没有意义。

10、存在性

我们可以在不访问属性值的情况下判断对象中是否存在这个属性

var myObject = {
  a:2
};
(‘a‘ in myObject);//true
(‘b‘ in myObject);//false

myObject.hasOwnProperty(‘a‘);// true
myObject.hasOwnProperty(‘b‘);//false

in 操作符会检查属性是否在对象及其[[Prototype]]原型链上,相比之下,hasOwnProperty()只会检查属性是否在myObject对象中,不会检查[[Prototype]]链

注意:in实际上检查的是某个属性是否存在。对于数组:4 in [2,4,6] 并不是true ,因为 [2,4,6] 包含的是属性名0,1,2没有4

 11、枚举

可枚举就相当于 可以出现在对象属性的遍历中

不影响存在性

for...in...这种枚举不仅会包含所有的数值索引还会包含所有可枚举属性

 

你不知道的js-混合对象-类

1、类是一种设计模式,许多语言提供了对于面向类软件设计的原生语法,js中也有类似的语法,但是和其他语言中的类完全不同。2、类意味着复制3、js并不会像类那样自动创建对象的副本。4、在继承或者实例化时,js的对象机... 查看详情

读书笔记-你不知道的js上-对象

好想要对象···   函数的调用位置不同会造成this绑定对象不同。但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂)  语法  对象声明有两个形式:  1、字面量=>varobj={...};  2、构造形式=&g... 查看详情

你不知道的js系列(33)-对象复制(代码片段)

JS初学者最常见的问题之一就是如何复制一个对象。看起来应该有一个内置的copy()方法,实际上比想象中的更复杂,我们无法选择一个默认的复制算法functionanotherFunction()/**...*/;varanotherObject=c:true;varanotherArray=[];varmyObject=  a:2, ... 查看详情

你不知道的js5-原型

1、原型[[prototype]]js中的对象有一个特殊的[[prototype]]内置属性,其实就是对于其他对象的引用,几乎所有的对象在创建时[[prototype]]属性都会被赋予一个非空的值使用for..in和in操作符都会查找对象的整条原型链所有普通的[[prototype]... 查看详情

《你不知道的js(中卷)》混合对象“类”(代码片段)

四、混合对象“类”:? 在研究类的具体机制之前,首先介绍面向类的设计模式:实例化(instantiation)、继承(inheritance)和(相对)多态(polymorphism)。一)、类理论:? 面向对象编程强调的是数据和操作数据的行为本质上是... 查看详情

你不知道的js系列(29)-对象属性(代码片段)

存储在对象容器内部的是这些属性的名称,它们就像指针(从技术角度来说是引用)一样,指向这些值真正的存储位置。 varmyObject=  a:2myObject.a;//2myObject[‘a‘];//2.语法通常被称为‘属性访问’,[]语法通常被称为&lsqu... 查看详情

你不知道的js系列(39)-对象遍历(代码片段)

for循环可以遍历数组varmyArray=[1,2,3];for(vari=0;i<myArray.length;i++)  console.log(myArray[i])//123ES5增加了数组的辅助迭代器,包括forEach(...)、every(...)、some(...)forEach(...)会遍历数组中的所有值并忽略回调函数的返回值every(...)会一直运行直... 查看详情

你不知道的js系列(30)-对象属性(可计算属性名)(代码片段)

如果你需要通过表达式来计算属性名,[]操作符就派上用场了。ES6中使用[]包裹一个表达式来当作属性名varprefix=‘foo‘;varmyObject=  [prefix+‘bar‘]:‘hello‘,  [prefix+‘baz‘]:‘world‘,myObject[‘foobar‘];//hellomyObject[‘foobaz‘];//world... 查看详情

《你不知道的javascript》——this和对象原型

 《你不知道的javascript》【3】——this和对象原型https://www.bilibili.com/video/BV1iE411P7UP 浅显的总结《你不知道的js》this指向          右查找的副作用:查找到顶层都找不到,就会抛出 查看详情

你不知道的this和class

 Ohno....我的This又丢失了???为什么我用Class‘实例化‘出来的对象会相互影响???####这些问题都是因为JS的运行机制造成的。在JS中所有的一切都是对象,而this是对象的一个属性。在对象被调用时,this动态的根据上下文环境... 查看详情

《你不知道的js》——this全面解析(代码片段)

默认绑定//全局对象用于默认绑定functionfoo()console.log(this.a)vara=2;foo();//2//严格模式下,不能将全局对象用于默认绑定functionfoo()‘usestrict‘;console.log(this.a)vara=2;foo();//TypeError:thisisundefined//在严格模式下调用foo()则不影响默认绑定func 查看详情

js局部变量和全局变量·你不知道的事

...明就可以使用变量;第二,js有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性。650)this.width=650;"src="https://s 查看详情

《你不知道的js(中卷)》行为委托(代码片段)

六、行为委托:? 总结第五章,JS中的[[Prototype]]机制就是对象之间的关联关系。一)、面向委托的设计:? 想要学习更直观的使用[[Prototype]],必须认识到它代表了一种不同于类的设计模式。1、类理论:? 类设计模式鼓励你在继承时... 查看详情

你不知道的js系列上(45)-显式混入(代码片段)

JS的对象机制并不会自动执行复制行为,由于其他语言中表现出来的复制行为,因此JS开发者也想出了一个方式来模拟类的复制行为,这个方法就是混入。我们先看第一种,显式混入。//非常简单的mixin()例子functionmixin(sourceObj,targe... 查看详情

《你不知道的javascript》原型

1[[Prototype]][[Prototype]]是对其他对象的引用,几乎所有对象在创建时[[Prototype]]属性会被赋予非空值。varmyObject={a:2}myObject.a;//2 引用对象属性时会触发[[Get]]操作,它会检查对象本身是否有这个属性,如果有就使用它,但a不在myObj... 查看详情

你不知道的高性能javascript

想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影。本文会分享一些高效的JavaScript的最佳实践,提高大家对JS的底层和实现原理的理解。数据存储计算机学科中有一个经典问题是通过改变数... 查看详情

你不知道的javascript

一、对象JavaScript简单类型有数字、字符串、布尔值、null、undefined,其他所有的值都是对象(数组、函数、正则表达式都是对象)。数字、字符串、布尔值虽然拥有方法(包装对象),但并不是对象。包装对象:每当读取一个基... 查看详情

js中你不知道的一些概念知识(代码片段)

DOM元素e的e.getAttribute(propName)和e.propName有什么区别和联系e.getAttribute(),是标准DOM操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性e.propName通常是在HTML文档中访问特定元素的... 查看详情