JavaScript基础知识-(对象)

JavaScript中所有的事物都是对象,字符串,数字,数组,日期,等等,JavaScript对象可以看作是属性的无序集合,每个属性都是一个键值对,JavaScript对象除了可以保持自有属性,还可以从一个称为原型的对象继承属性。对象的方法通常是继承的属性,这种“原型式继承”是JavaScript的核心特征
1,初识对象

对象最常见的用法是:创建,设置,查找,删除,检测和枚举它的属性。属性包括名字和值。属性名可以是包含空字符串在内的任意字符串,属性值可以是任意JavaScript的值。除了名字和值意外,每个属性还有一些与之相关的值,称为:属性特性,
  (1) 可写,表明是否可以设置改属性的值
  (2) 可枚举,表明是否可以通过for/in循环返回该属性
  (3) 可配置,表明是否可以三次或者修改该属性
每个对象还拥有三个相关的对象特性
  (1) 对象的原型:指向另外一个对象,本对象的属性继承自它的原型对象
  (2) 对象的类:是一个标识对象类型的字符串
  (3) 对象的扩展标记:指明了是否可以向该对象添加新的属性

2,对象的创建
(1) 对象直接量
    var obj = {x:1,b:2}  
(2) 通过new创建  
    var obj = new Array()  
    var date = new Date()  
(3) 通过Object.create()创建  
    var obj = Object.create()
3,了解原型

每一个JavaScript对象(null除外)都和另一个对象相关联,‘另一个’对象就是我们熟知的原型,每一个对象都从原型继承属性。用对象直接量创建的对象都具有同一个原型对象,通过Object.prototype获得对原型对象的引用。通过new创建的对象,原型就是构造函数的prototype属性的值,比如:Array.prototype,Date.prototype。没有原型对象的:Object.prototype就只其中之一。普通对象都具有原型,Array.prototype的属性继承自:Object.prototye, 因此:new Date()创建的Date对象的属性同时继承Date.prototype,和Object.prototye,这就是原型链

4,属性的查询和设置

可以通过点(.)或者方括号([]),比如:obj.a 或者 obj[‘a’]都可以获得属性值,   ECMAScript 3中,点运算符后的标识符不能使用保留字,ES5放宽了限制,常见的两种例外情况:对象属性名是个关键字,那么只有用中括号去访问,如果属性名是个不确定参数,那么也只能用中括号去访问

5,删除属性

delete运算符只能删除自由属性,不能删除继承属性,也不能删除那些不可配置的属性,返回值是true或者false

6,检测属性

判断某个属性是否存在于某个对象中,可以通过in运算符,hasOwnProperty() 和proertyIsEnumerable()方法
  (1)in运算符 (检测自有属性和继承属性)

var obj = { x: 1, y: 2}
 "x" in obj
 // 左侧是属性名,右侧是对象,如果对象的自有属性或继承属性含有这个属性,返回true

(2)hasOwnProperty()函数(检测自有属性)

var obj = { x:1, y:2}  
    obj.hasOwnProperty('x')
// hasOwnProperty()用来检测是否是对象的自有属性,不会查找原型属性的

(3)propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到自有属性且这个属性的可枚举性为true的时候,才返回true

7,枚举属性

枚举属性: for-in 循环。
  for-in循环可以在循环体中遍历对象中所有可枚举的属性,包括自有属性和继承属性,把属性名称赋值给循环变量,切记:对象继承的内置方法不可枚举

var obj = { x:1, y:2, z:3};                // 三个都是可枚举的属性
    obj.propertyIsEnumerabel('toString')  // =>false 不可枚举
    for(item in obj) {
        console.log(item)                // 输出:x,y,z,没有toString
    }
// 切记: 对象继承的内置方法是不可枚举的
for(item in obj){
    if(!obj.hasOwnProperty('item')
    continue;   // 跳过继承的属性
}
for(item in obj) {
    if(typeof obj[item] === 'function') {
        continue;  // 跳过方法
    }
}

除了for-in循环之外,还有两个方法
  (1)Object.keys(), 返回一个数组,这个数组有对象中可枚举的自有属性的名称组成
  (2)Object.getOwnPropertyNames() 返回数组,只是它返回对象的所有自有属性的名称,而不仅仅是可枚举的属性,还包括不可枚举属性

8,属性getter和setter

对象属性是由名字,值,和一组特性构成。属性值可以用一个或者两个方法替代,这两个方法就是getter,和setter,简称“存取器属性”。
  数据属性只有一个简单的值。
  和数据属性一样,存取器属性也是可以继承的

9,属性的特性

可以认为一个属性包含:一个名字和4个特性。

  • 数据属性4个特性:值(value),可写性(writable),可枚举性,可配置性
  • 存取器属性:取(get),写入(set),可枚举性,可配置性
    为了实现属性特性的查询和设置操作,ES5定义了‘属性描述符’对象
    数据属性的描述符对象属性有:value, writable, enumerable, configurable
    存取器属性的描述符对象属性:get, set, enumerable, configurable
    通过调用Object.getOwnPropertyDescriptor() 可获取特定属性的属性描述符
var obj = { x:1, y:2, z:3};
console.log(Object.getOwnPropertyDescriptor(obj, 'x'))
// 返回: {value:1, writable:true, enumerable:true, configurable: true}

存取器属性:{set: undefined,get:function,enumerable:true,configurable:true}
 Object.getOwnPropertyDescriptor()只能得到自有属性
 要想获得继承属性的特性,需要遍历原型链:用Object.getPrototypeOf()
 想要设置属性特性,或者新建属性具有什么特性:用Object.definePeoperty()

    var obj = {};
    Object.defineProperty(obj, 'x',{
    	value: 'zlm',
    	writable: true,     // 可编辑
    	enumerable: false, //不可枚举
    	configurable: true
    })
    console.log(obj.x) // => zlm 属性是存在的
    console.log(Object.keys(obj)) // =>[] 不可枚举,所以输出空数组 []
    Object.defineProperty(obj,'x', {
    	writable:false
    })
    obj.x = 222;
    console.log(obj.x)  // =>zlm,值没有改变,因为是不可写入
    Object.defineProperty(obj, 'x',{
    	value: 444
    })
    console.log(obj.x) // =>444 属性依然可配置,所以值可以修改
    Object.defineProperty(obj, 'x', {
    	get: function() {
    		return 555;
    	}
    })
    console.log(obj.x) // =>555 将x从数据属性修改为存取器属性

注意:Object.defineProperty()不能修改继承属性,同时要修改或创建多个属性,使用:Object.defineProperties()

// 第一个参数是:要修改的对象
// 第二个参数是:一个映射表,包含新建或者修改的属性名称和属性描述符
  var p = Object.defineProperties({},{
  	x: {value:1,writable:true,enumerable:true,configurable:true},
  	y: {value:2,writable:true,enumerable:true,configurable:true},
  	z: {
  		get: function() { return this.x * this.x + this.y *this.y },
  		enumerable:true,
  		configurable: true
  	}
  })
  console.log(p.x , p.y , p.z)

属性特性的复制

Object.defineProperty(Object.prototype, 'extentd', {
  	writable:true,
  	enumerable: false,
  	configurable:true,
  	value: function(o) {
  	   //遍历o对象中所有的自有属性
  		var names = Object.getOwnPropertyNames(o)  
  		for(var i =0; i< names.length; i++) {
  			if(names[i] in this) continue
  			// 获取o中的属性的描述符
  			var desc = Object.getOwnPropertyDescriptor(names[i])
  			// 给当前对象创建同样的属性描述符
  			Object.defineProperty(this,names[i],desc)
  		}
  	}
  })
10,对象的是三个属性
  • 原型
  • 可扩张性
    (1)原型属性是在实例对象创建之初就设置好的,
    通过对象直接量创建的对象,原型是:Object.prototype()
    通过new创建的对象:原型:构成函数.prototype
    通过Object.create()创建的对象,原型是:第一个参数
    想要检测一个对象是否是另一个对象的原型,通过:isPrototypeOf()方法
    例如:p.isPrototypeOf(o) 检测p是否是o的原型
    (2)类的属性
    获取对象的类方法:调用对象的toString()方法,提取第8个和倒数第二位的字符
function classof(o) {
	if(o === null) return "NULL";
	if(p === undefined) return "Undefined";
	return Object.prototype.toString.call(o).slice(8, -1)
	}
	classof({})
	classof(null)
	classof("")
	classof(false)
	classof([])
	classof(new Date())
	classof(/,/)
	classof(window)

(3)对象的可扩展性表示是否可以给对象添加新属性,所有内置对象和自定义对象都是显示可扩展的
ES5提供了可以用来查询和设置对象的可扩展性函数:Object.esExtensible()
设置对象为不可扩展,封闭的:Object.preventExtensions(),Object.seal()
检测对象是否封闭:Object.isSealed()
更严格的锁定对象,冻结:Object.freeze()
检测对象是否冻结:Object.isFrozen()

11,对象的序列化

对象的序列化是指:将对象的状态转换为字符串,也可将字符串还原为对象
  ES5提供了内置函数:JSON.stringify() 用来序列化,JSON.parse()还原对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值