JavaScript对象

1. 对象

JS中万物皆对象
字符串、布尔、数值也是通过对象方法创建的(通过原型链进行调用的),也可以调用对象原始方法toString

var str = 'xiaoming';
str.toString();//调用时,JS会自动进行装箱操作 String('str').toString() -> 拆箱 str

2. 对象创建

2.1. 字面量的方式

var stu = {
    name:'xiaoming',
    cook:function(){
        console.log(this.name + '去做饭')
    },
}

2.2. 构造函数的方式

var stu = new Object();
stu.name = "xiaoming";
stu.cook = function(){
    console.log('hello');
}

3. 对象遍历

for(自定义变量名 in 数组/对象){
    执行代码
}
for(var key in obj){
    var value=obj[key];
}

能被for…in语句打印的属性称为可枚举属性(默认情况下,自定义属性都是可枚举的)

4. 原型、原型链和继承

显式原型prototype
隐式原型__proto__

4.1. 构造函数、原型和实例的关系

每个构造函数都有一个prototype指针指向其原型对象,原型对象都包含一个指向其构造函数的指针constructor,而实例都包含一个指向原型对象的内部指针__proto__
原型和构造函数

4.2. 原型链

在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的,所有的对象都直接或间接继承Object。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条。
原型链
图中d1继承Animal,Animal继承Function,Function继承Object。
子类添加或覆盖父类方法:
子类向父类中添加新的方法或覆盖父类的方法时,需要在原型赋值(Dog.prototypr=new Animal())之后进行

4.3. 原型链的破坏

以字面量的方式创建原型方法会破话之前的原型链,相当于重写了原型链。

function Animal(){
    this.name = 'animal';
}
Animal.prototype.getAnimalName = function(){
    console.log(this.name);
}
function Dog(){
    this.name = 'dog';
}
Dog.prototype = new Animal();
Dog.prototype = {
    getDogName(){
        console.log(this.name);
    },
    someOtherMethod(){
        return false;
    }
};
var d1 = new Dog();
d1.getAnimalName();//出错

在以上代码中,子类的原型在被赋值为Animal的实例后,又被一个对象字面量覆盖了。覆盖后的原型是一个Object的实例,而不再是Animal的实例。因此原型链断了,Dog和Animal之间没有联系了。

4.4. 检测对象是否在同一个原型链中

  1. isPrototypeOf():检测一个对象是否存在于另一个对象的原型链上(原型的指向)
function Animal(){}
function Dog(){}

var d2 = new Dog();
console.log(Animal.prototype.isPrototypeOf(d2));//false

Dog.prototype = new Animal();//原型链继承
var d2 = new Dog();
console.log(Animal.prototype.isPrototypeOf(d2));//true

var obj = {};
console.log(Object.prototype.isPrototypeOf(obj));//true
  1. instanceof:检测一个对象是否是某个构造函数的实例(new)
function Animal(){}
var d1 = new Animal();
connsole.log(d1 instanceof Animal);//true

4.5. 字符串地区对应

toLocaleString() 返回对象的字符串表示,该字符串与执行环境的地区对应

var now = new Date();
console.log(now);
console.log(now.toString());//Thu Oct 15 2020 21:40:38 GMT+0800 (中国标准时间)
console.log(now.toLocaleString());//2020/10/15 下午9:40:38

5. 属性

5.1. 数据属性

  1. Object.defineProperty设置某一个对象的某一个属性的原始属性
Object.defineProperty(obj,'name',{
   configurable:true,//表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性
   enumerable:true,//表示能否通过for-in循环返回属性
   writable:true,//表示能否修改属性的值
   value:'terry'//包含这个属性的数据值
})
  1. Object.definePropertys一次设置对象的多个属性的原始属性
Object.defineProperty(obj,{
	age:{
		configurable:false;
	},
	sex:{
		configurable:false;
	}
})
  1. Object.getOwnPropertyDescriptor获取到属性的描述符
  2. 总结configurable:当configurable设为false时,
    • 不可以通过delete去删除该属性从而重新定义属性;
    • 不可以转化为访问器属性;
    • configurable和enumerable不可被修改;
    • writable可单向修改为false,但不可以由false改为true;
    • value是否可修改根据writable而定。

当configurable为false时,用delete删除该属性,在非严格模式下,不会报错,但操作被忽略,在严格模式下会报错;其他不可被修改的特性修改时会报错。

5.2. 访问器属性

访问器属性不包含数据值,包含的是一对get和set方法,通过这两个方法来进行读写访问器属性操作。访问器属性不能直接定义,要通过Object.defineProperty()这个Object的静态方法来定义

访问器属性configurable默认为false

var obj = {
	_num:0
}
Object.defineProperty(obj,'num',{
	set(num){
		this._num = num
	},//在num的值被设置时调用,默认隐式调用
	get(num){
		return '数字:' + this._num
	}//在num的值被获取时调用,默认隐式调用
})

数据描述符value、writable 和访问器描述符get、set不能同时设置

6. 属性操作

6.1. 属性访问

var stu = new Object();
stu.name = 'red';
var n = 'name';
//点表示法
console.log(stu.name);
//中括号表示法
console.log(stu['name']);//red
console.log(stu[n]);//red
//中括号里必须是计算结果为字符串的表达式   
//不加引号会默认为变量名

6.2. 属性删除

delete 属性访问表达式
delete stu.name
delete只会删除对象自有属性,不能删除继承属性

6.3. 属性检测

  1. in 检测某属性是否是某对象的自有属性或者是继承属性
var obj = new Object();
obj.name = "terry";
obj.age = 12;
obj.gender="male"
console.log("name" in obj);//true 自有
console.log("toString" in obj);//true 继承
  1. hasOwnProperty()检测给定的属性是否是对象的自有属性,对于继承属性将返回false
var obj = new Object();
obj.name = "terry";
obj.age = 12;
obj.gender="male"
console.log(obj.hasOwnProperty("name"));//true
  1. propertyIsEnumerable() 检测给定的属性是否是该对象的自有属性,并且该属性是可枚举的。通常由JS代码创建的属性都是可枚举的,但是可以使用特殊的方法改变可枚举性。
var obj = new Object();
obj.name = "terry";
obj.age = 12;
obj.gender="male"
console.log(obj.propertyIsEnumerable("name"));//true
  1. 自定义hasPrototypeProperty() 函数检测既定属性是否存在对象的原型中
var obj = {
    a: 'a1',
    b: 'b2'
}
 
Object.prototype.c = "c3";
 
function hasPrototypeProperty(obj, property) {
    return !obj.hasOwnProperty(property) && property in obj
}
 
console.log(hasPrototypeProperty(obj, "c"))    // true
console.log(hasPrototypeProperty(obj, "b"))    // false

7. 数据类型转换

7.1. Object类型到Boolean类型

除了空引用(null)会转换为false,其他都被转换为true(空对象也为true)

7.2. Object类型转换为String类型

通过toString()和String()进行转换

valueOf和toString的区别:

  1. 这两个方法都是对象的原始方法
  2. valueOf为对象的原始值,通常不会显示的调用,通常有JS自动在后台进行调用
  3. toString本身的一个作用是做字符串的转换,也会进行自动调用
  4. 如果重写了两个方法,在进行运算时,优先调用valueOf,在进行显示时,优先调用toStirng。如果只重写了一个方法,无论运算还是显示,都会调用该方法

拓展:可以用valueOf()实现一个累加的实例,每次调用obj时valueOf()都会调用
(num在valueOf()中被引用,所以不会被垃圾回收机制回收)

var obj = {
    num:1,
    toString:function(){
        return this.num+1;
    },
    valueOf:function(){
        return this.num++;
    }
}
console.log(obj==1);//true
console.log(obj==2);//true
console.log(obj==3);//true

7.3. Object类型转换为Number类型

  1. 如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
  2. 如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
  3. 如果两个方法都没有重写,则返回NaN

8. 值传递与引用传递(址传递)

  • 基本数据类型的变量:
    可以直接操作保存在变量中的实际的值,参数传递的时候传递的是实际值
  • 引用数据类型的变量:
    不能直接操作对象的内存空间,实际上是在操作对象的引用,参数传递的时候传递的是引用地址

9. 对象序列化

将对象转换为字符串的描述,解决对象在io中传递的问题
undefined值不能序列化和反序列化

  1. 常规转换
    obj.toString()
  2. 转换为json字符串
    JSON.stringify(obj) //只能序列化对象可枚举的自有属性
var obj = {
	name:"briup",
	age:12
};
console.log(obj);  //object类型打印的结果  { name: 'briup', age: 12 }

// 将对象转换为JSON字符串
var json = JSON.stringify(obj);
console.log(json);//string类型的字符串 {"name":"briup","age":12}

// 将JSON字符串转换为对象
var json = '{"name":"briup","age":12}';
//json在进行反序列化的时候是不支持单引号的
var obj = JSON.parse(json);
console.log(obj);// { name: 'briup', age: 12 }

  1. 转换为查询字符串
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值