JavaScript深入理解之对象
1.这里首先解释一下JS中数据类型和对象,这两个东西经常弄混。
六种主要数据类型 | 九种内置对象 |
---|---|
string | String |
boolean | Boolean |
number | Number |
object | Object |
null | Function |
undefined | Array |
RegExp | |
Date | |
Error |
2.对象两种定义形式:字面量和构造形式
var obj = { //字面量
key: value
// ...
}
let _obj = new Object(); //构造形式
_obj.key = value;
3.在JavaScript中,这九种对象实际是是一些内置函数,这些内置函数可以当作构造函数来实用,从而可以构造一个对应子类型的新对象,对九种内置对象进行typeof运算,全部返回function 。
let a = "aaa"; // a是一个字面量,并不是一个对象
let aa = a instanceof String;
console.dir(aa); // => false
let b = new String('bbb'); // 利用构造函数String来新建一个字符串对象
let bb = b instanceof String;
console.dir(bb); // => true
4.关于对象的值
* 对象的内容是由一些存储在特定命名位置的至组成,称之为属性,而存储在对象内部的是这些属性的指针(或者说是引用),并不是存储的真正的属性值。 *
var a = {
name: 9
}
var b = a;
console.log(a.name); // => 9
console.log(b.name); // => 9
b.name = 2;
console.log(a.name); // => 2
console.log(b.name); // => 2
var b = {
name: 10
}
console.log(a.name); // => 2
console.log(b.name); // => 10
* 上例分析:a为一个对象,b是对a的引用,即a和b指向的同一块内存,所以前两个输出一样,当b修改时,即a和b指向的同一块地址的内容发生改变,所以a也会体现出来,第三个和第四个的结果一样,当b被重新定义时,b指向了一块新的内存地址,a还是指向原来的内存,所以最后两个不一样 *
5.对象的属性和方法
var a = {
bar: 123,
foo: function() {
console.log('foo');
}
}
var someFoo = a.foo;
console.log(type someFoo); // => function
someFoo(); // => foo ,括号是让函数立即执行,作用相当于立即函数后面的一堆括号
* 对象的属性和方法其实是一样的,只是某一个属性为一个函数,所以大家都习惯称该属性为方法*
6.typeof —– 获取变量的类型
* typeof用来获取变量的数据类型,并不是判断是属于什么对象,typeof的返回值有六种,看下图代码 *
console.dir(typeof '123'); // => 'string'
console.dir(typeof true); // => 'boolean'
console.dir(typeof 123); // => 'number'
console.dir(typeof {a:123}); // => 'object'
console.dir(typeof [123]); // => 'object'
console.dir(typeof null); // => 'object'
console.dir(typeof undefined); // => 'undefined'
console.dir(typeof function(){}); // => 'function'
7.instanceof —– 判断一个对象是否由某个指定的构造器函数所创建
console.dir('123' instanceof String); // => false
console.dir(true instanceof Boolean); // => false
console.dir(123 instanceof Number); // => false
console.dir({a:123} instanceof Object); // => true
console.dir(function(){} instanceof Function); // => true
console.dir([123] instanceof Array); // => true
* 上例中:前面三个返回的是false,为什么呢,难道’123’不是属于字符串吗?其实是这样的,’123’是字符串,console.log(typeof 123)会打印出string,但是instanceof操作符要求左边的是一个对象,instanceof是判断一个对象是否由某个构造器函数生成,即前提条件是:instanceof左边要是对象,右边要是函数;否则进行instanceof运算是没有意义的。’123’只是一个字面量,并不是一个对象,因此会返回false。第二个和第三个输出是同样的道理,要想生成一个’123’字符串对象,如下:*
let aa = new String('123');
console.log(aa instanceof String); // => true
console.log(aa); // => String { 0:"1", 1:"2", 2:"3"}
console.log(typeof aa); // => object
8.constructor —– 构造器属性
let aa = new String('123');
console.log(aa.constructor); // => String()
console.log(typeof aa.constructor); // => function
console.log(aa instanceof String); // => true
* 当我们创建一个对象,该独享同时被赋予一种特殊的属性,constructor,称之为构造器属性,该属性是一个指向用于创建该对象的构造器函数的引用,即对象的constructor属性值指向这个对象创建是所引用的构造器函数,当(newObject instanceof FunctionName)为true时,newObject.constructor指向FunctionName*
9.对象属性描述符
let a = {
aa: 123
}
let b = Object.getOwnPropertyDescriptor(a, 'aa');
console.log(b);
/* {
value: 2, //该属性的值
writable: true, //该属性值是否可修改
enumberable: true, //遍历该对象时,该属性是否被遍历
configurable: true //该属性是否可配置,即value、writable、enumerable是否可修改
}
*/
10.对象属性存在 —– in、hasOwnProperty();
* in操作符会检查属性是否存在对象及其原型原型链中,hasOwnProperty()只会检车属性是否存在对象中. *
function AA(){
this.a = 123;
this.b = 456;
}
AA.prototype.c = 789;
let aa = new AA();
let bb = 'a' in aa;
let cc = 'c' in aa;
let dd = aa.hasOwnProperty('c');
console.log(bb); // => true
console.log(cc); // => true
console.log(dd); // => false
11.对象属性遍历 —– for…in、for…of
let a = [1, 2, 3];
let b = {
aa: 1,
bb: 2,
cc: 3
}
for(let i in a){
console.dir(i); // '0' '1' '2'
}
for(let i in b){
console.dir(i) // 'aa' 'bb' 'cc'
}
for(let i of a){
console.dir(i); // 1 2 3
}
* for…in用来遍历对象的索引(属性),但是遍历对象属性时的顺序可能是不确定的,即不是按顺序便利,for…of用来遍历含有iterator接口的对象的属性值 *