权威指南学习心得-对象

对象的属性特性:

1、可写(writable)

2、可枚举(enumerable)

3、可配置configurable

对象特性:

1、对象的原型(prototype)

2、对象的类(class)

3、对象的扩展标记

对象的种类

1、内置对象(数组、函数、日期和正则表达式)

2、宿主对象 htmlelement

3、自定义对象

属性的种类

自有属性

继承属性

原型:

每一个js对象(null和Object.prototype除外)都和另一个对象相关联,每一个对象都从原型继承属性

对象直接量({})和new Object的原型对象是Object.prototype

函数对象(function(){})的原型是Function.prototype

Date对象(new Date())的原型是Date.prototype

Array对象(new Array或者[])的原型是Array.prototype

RegExp对象(new RegExp())的原型是RegExp的原型是RegExp.prototype,

new加构造函数的对象的原型是构造函数的原型

其他原型对象都是普通对象,普通对象都具有原型。所有的内置构造函数(Function Array Date RegExp)以及自定义的构造函数都具有一个继承自Object.prototy的原型,比如Data.prototype的属性继承自Object.prototype,因此由new Date()创建的Date对象的属性同时继承自Date.prototype和Object.prototype.这一系列连接的原型对象就是所谓的原型链

Object.create()创建一个新对象,其中第一个参数是这个新对象的原型

var o={x:1,y:2};
var t=Object.create(o);
console.log(t.x);//1
var t2=console.log(Object.create(Object.prototype));//{}

function inherit(p){
  if(p==null) throw TypeError();
  var t=typeof p;
  if(t!=="object"&&t!=="function"){
    throw TypeError();
  }
 var f=function(){};
  f.prototype=p;
  return new f();
  
}

var t3=inherit(o);
console.log(t3.x);//1

继承 

属性赋值要么失败,要么创建一个属性,要么在原始对象中设置属性

属性访问错误

查询一个不存在的属性并不会报错,如果在对象O自身的属性或者继承的属性中均未找到属性x,属性表达式o.x则返回undefined

但是。如果对象不存在,那么试图查询这个不存在的对象的属性就会报错

简练和保险的做法

var len=book&&book.subtitle&&book.subtitle.length;

 delete只是断开属性和宿主对象的关系,而不会去操作属性中的属性

var o={x:1};
var b=o.x;
delete o.x;
console.log(o.x);//undefined
console.log(b);//1

delete运算符只能删除自有属性,不能删除继承属性

当delete表达式删除成功或者没有任何副作用(比如删除不存在的属性)时,它返回true。如果delete后不是一个属性访问表达式,delete同样返回true

var 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

delete不能删除那些可配置属性为false的属性。某内置对象的属性是不可配置的,比如通过变量声明和函数声明创建的全局对象的属性。

检测属性

in 如果对象属性或者继承属性中包含这个属性则返回true

hasOwnProperty 检测给定的名字是否是对象的自有属性,对于继承属性它将返回false;

propertyIsEnmerable 只有检测到是自有属性且这个属性的可枚举为true时它才能返回true

var o={x:1};
console.log(o.propertyIsEnumerable("x"));//true
console.log(o.propertyIsEnumerable("toString()"));//false(继承属性)

console.log(Object.prototype.propertyIsEnumerable("toString()"));//false(不可枚举)


console.log(o.hasOwnProperty("x"));//true
console.log(o.hasOwnProperty("toString()"));//继承属性

可以用!==来判断一个属性是否属于undefined

var o={x:1};
var cs=console.log;
cs(o.x!==undefined);//true
cs(o.y!==undefined);false
cs(o.toString()!==undefined);//true

判读属性是否为真值(不属于undefined null false "" 0或者NaN);

in(o.x) o.x*2=;

枚举属性

for/in

var o={x:1,y:2};
for(var p in o){
  if(!o.hasOwnProperty(p)){
    continue;
  }//过滤继承属性
  if(typeof o[p]=="function"){
    continue;
  }//过滤方法
  console.log(p);
}
function extend(o,p){//循环p的可枚举属性,复制到o中,如果o和p有同名的属性,则覆盖o中的属性
  for(var prop in p){
    o[prop]=p[prop];
  }
  return o;
}
function merge(o,p){//把p的属性复制到o中,如果有同名的属性,则O的属性不受影响
  for(var prop in p){
    if(o.hasOwnProperty(prop)){
      continue;
    }
    o[prop]=p[prop];
  }
  return o;
}
function restrict(o,p){//如果p中不存在o的同名属性,则删掉这个属性
  for(var prop in o){
    if(!(prop in p)){
      delete o[prop];
    }
  }
  return o;
}
function substract(o,p){//如果p中存在o的同名属性,则删掉这个属性
  for(var prop in p){
    delete o[prop];
  }
}

function union(o,p){//返回一个新对象,这个对象同时拥有o的属性和p的属性,如果有同名属性,使用p中的属性值
  return extend(extend({},o),p);
}
function intersection(o,p){//返回一个新对象,这个对象拥有同时在o和p存在的属性
return restrict(extend({},o),p); } function keys(o){//返回一个数组,这个数组包含的是o中可枚举的自有属性的名字 if(typeof o!=="object"){ throw TypeError(); } var result=[]; for(var prop in o){ if(o.hasOwnProperty(prop)){ result.push(o[prop]); } } return result; }

object.keys 返回一个数组,这个数组有对象中可枚举的自有属性的名称组成

object.getOwnPropertyNames() 返回对象的所有自有属性的名称,而不仅仅是可枚举的属性

属性getter和setter

var p={
  x:1.0,
  y:1.0,
  get r(){
    return Math.sqrt(this.x*this.x+this.y*this.y);
  },
  set r(newvlaue){
    var oldvlue=Math.sqrt(this.x*this.x+this.y*this.y);
    var ratio=newvlaue/oldvlue;
    this.x*=ratio;
    this.y*=ratio;
  }
};

console.log(p.r);

存取器属性定义为一个或者两个和属性同名的函数,而且是可以继承的

数据属性:value writable(bool) enumerable(bool) configurable(bool)

存取器属性:get(function) set enumerable configurable

Object.getOwnPropertyDescriptor 可以获得某个对象特定属性的属性描述

对于继承属性和不存在的属性,返回undefined

Object.defineProperty  设置属性的特性或者想让新建属性具有某种特性

不必包含4个特性,对于新建创的属性来说。默认的特性值是false或者undefined,对于修改的已有属性来说,默认的特性值没有做任何修改,不能修改继承属性

同时修改或者创建多个属性, Object.defineProperties()

对象的三个属性:prototype class(类属性) 可扩展性

对象的原型属性 对象创建之初就设置好

将对象作为参数传入Object.getPrototypeOf()可以查询到对象的原型,在em3中经常使用表达式o.constructor.prototype来检测一个对象的原型,通过new表达式创建的对象,通常继承一个constructor属性,这个属性指代创建了这个对象的构造函数。这个方法并不可靠

比如。通过对象直接量或者Object.create创建的对象包含一个名为constructor的属性,这个属性指代Object()构造函数。因此。constructor.prototype才是对象直接量的真正原型,但对于通过Object.create创建的对象则往往不是这样

var o={x:1};
console.log(o.constructor);//function Object(){}
console.log(o.constructor.prototype);//{}
console.log(Object.getPrototypeOf(o));//{}
var p=Object.create(o);
console.log(p.constructor);//function Object(){}
console.log(p.constructor.prototype);//object{}
console.log(Object.getPrototypeOf(p));//{x:1}

要检测一个对象是否后另一对象的原型(或者处于原型链),请使用isPrototypeOf()方法

和instranceof的区别

isPrototypeOf()左边是原型对象,参数是查询对象 判断原型对象是否在查询对象的原型链上

instranceof 左边是查询对象 右边是构造函数     判断构造函数的prototype时候在对象的原型链上

var p={x:1};
var o=Object.create(p);
console.log(p.isPrototypeOf(o));//true
console.log(Object.prototype.isPrototypeOf(o));//true

在火狐和谷歌浏览器中可以直接用__proto__来直接查询或者设置对象的原型,但在Ie中没有实现

var p={x:1};
var o=Object.create(p);
console.log(p.__proto__);//{}
console.log(o.__proto__);//{x:1}

 对象的类属性是个一个字符串,用以表示对象的类型信息,只有一种间接的方法查询,默认的toString()方法(继承自Object.prototype)返回如下格式的字符串:

[object class]

因此要的对象的类,可以调用对象的toString()方法,然后提取已返回字符串的第8到倒数第二位置之间的字符

var p={x:1};
var a=[];
function getClass(o){
  if(o===null) return "Null";
  if(o===undefined) return "Undefined";
  return Object.prototype.toString.call(o).slice(8,-1);
}
console.log(getClass(a));//Array
console.log(getClass(p));//Object
console.log(getClass(1));//Number


function getClass(o){
  if(o===null) return "Null";
  if(o===undefined) return "Undefined";
  return Object.prototype.toString.call(o).slice(8,-1);
}
console.log(getClass({}));//Object
console.log(getClass([]));//Array
console.log(getClass(/./));//RegExp
console.log(getClass(new Date()));//Date
console.log(getClass(window));//global
var f=function(){};
console.log(getClass(new f()));//Object

JSON.stringgify(o) 对象转换为字符串 

JSON.parse(s) 字符串还原为对象

支持对象、数组、字符串、无穷大数字、true、false和null。并且它们可以序列化和还原。NaN Infinity和-Infinity序列化的结果是null,日期对象序列化的结果是ISO格式的日期字符串(参照Date.toJSON()函数),但JSON.parse()依然保留它们自己的字符串形态,而不是还原。函数、RegExp、Error和undefined值不能序列化和还原。JSON.stringgify()只能序列化对象可枚举的自有属性,对于一个不能序列化的属性,在序列化的输出字符串中会将这个属性省略掉

var n=new Date();
console.log(n);//Tue Dec 15 2015 19:37:54 GMT+0800 (中国标准时间) console.log(JSON.stringify(n));//"2015-12-15T11:36:45.826Z" console.log(n.toJSON());//2015-12-15T11:36:45.826Z console.log(JSON.parse(JSON.stringify(n)));//2015-12-15T11:36:45.826Z

默认的toString()方法返回值带有的信息量很少(可以检测对象的类型),例如:

var s={x:1,y:2}.toString();//"[object object]"

由于默认的toString方法并不会输出很多有用的信息。因此很多类都带有自定义的toString。例如,当数组转换为字符串的时候,结果是一个数组元素列表,只是每个元素都转换为了字符串,当函数转换为字符串的时候,得到函数的源代码

toLocaleString() Date和Number类对toLocaleString()做了定制,可以用它对数字、日期和时间做本地化的转换。Array唯一的不同是每个数组元素都会调用toLocaleString()方法,而不是各自的toString方法

原文地址:https://www.cnblogs.com/yhf286/p/5046441.html