对象

js中没有必要为每一个对象实例创建类或者蓝图。可以在运行的时候创建它,同时你可以为对象添加任何的属性和方法。事实上在js中所有的对象都是一个关联数组。

   var cc=new Object();
    cc.firstName="sa";
    cc.sayName=function () {
        console.log(this.firstName);
    };
    cc["firstName"]="dd";
    cc["sayName"]();    //dd

创建对象

字面量的方式

 var cc={
        "aaa":"sas",
        "author":{
            "ll":"赵文娟",
            "mm":"牛执行"
        }
    }
    console.log(cc.author.mm);

关键字new

new关键字 +一个构造函数 (内置对象)
之所以js可以使用以上两种方式来创建对象,就是因为在js的内部是通过关联数组来实现对象的。

按属性访问和按键访问

按属性访问 对象.属性
按键访问 对象[属性]
可计算属性名

var prefix="sa";
    var myObject={
        [prefix+"1"]:"hello",
        [prefix+"2"]:"wqwqq",
    }
    console.log(myObject["sa1"]);

但是在外部给数组添加非数字的属性的时候不会改变数组的长度

var arr=["foo",42];
    arr["baz"]="sas";
    console.log(arr.length);  //2

加一个数字的属性的时候则会改变数组的长度

var arr=["foo",42];
    arr["3"]="sas";
    console.log(arr.length);  //2
    for(var i=0;i<arr.length;i++){
        console.log(arr[i]);   //中间会有一个undefined
    }

对象的属性描述符:
以下这两个方法都是在ES5以后才可以使用的。
writable enumerable configurable
getOwnPropertyDescriptor得到了对象的描述符

var myObject={a:2}
  //Object {value: 2, writable: true, enumerable: true, configurable: true}
    console.log(Object.getOwnPropertyDescriptor(myObject,"a"));
    myObject.a=10;
    console.log(myObject.a);

设置对象的描述符
defineProperty()函数

  var myObject={a:2}
  //Object {value: 2, writable: true, enumerable: true, configurable: true}
  Object.defineProperty(myObject,"a",{value:2,writable:false,configurable:false,enumerable:false});
  myObject.a=10;
    console.log(myObject.a);    //2

虽然试图修改a的值,但是没有修改成功。但是非严格模式下不会报错。严格模式下则会报错。

对象禁止拓展

Object.preventExtensions()这个方法就可以禁止拓展

 var myObject={a:2}
    Object.preventExtensions(myObject);
    myObject.b=3;
    console.log(myObject.b);   //undefined

对象的复制

json提供的一种巧妙地复制方法

   var aa={a:1,cc:function () {
       console.log(this.a);
   }};
    var b=JSON.parse(JSON.stringify(aa));
   aa.cc();   //1
   console.log(b.a);
   b.a=3;
   console.log(b.a);
   b.cc();   //b.cc is not a function

运行到b.cc()会报错。说明这种方法是浅复制。
使用Object.assign()实现复制

  var aa={a:1,cc:function () {
       console.log(this.a);
   }};
    var b=Object.assign(aa);
   aa.cc();   //1
   console.log(b.a);
   b.a=3;
   console.log(b.a);
   b.cc();   //3

Getter和Setter

getter是一个隐藏函数会在获取属性的时候调用,
setter也是一个隐藏函数,会在设置属性值时调用。
当给一个属性定义getter,setter的时候,js会忽略这个属性的value和writeable特性,取而代之的是比较关心getter和setter

   var myobject={ get a(){return 2;}}
    myobject.a=3;
    Object.defineProperty(myobject,"b",{get:function () {
        return this.a*2;
    }})
   myobject.a=20;
   myobject.b=40;
    console.log(myobject.a);   //2
    console.log(myobject.b);   //4

同时如果在定义类的时候,如果只给a属性定义了get方法,那么所有的set操作都是没有意义的。所以一个即可以读取也可以修改的属性应该set和get方法都有。

 var myobject={ get a(){return this._a_;},set a(a){this._a_=a}}
    Object.defineProperty(myobject,"b",{get:function () {
        return this.a*2;
    }})
   myobject.a=20;
   myobject.b=40;
    console.log(myobject.a);   //20
    console.log(myobject.b);   //40

为什么b会被修改???

 var myobject={ get a(){return this._a_;},set a(a){this._a_=a}}
    Object.defineProperty(myobject,"b",{get:function () {
        return 5;
    }})
   myobject.a=20;
   myobject.b=40;
    console.log(myobject.a);   //20
    console.log(myobject.b);   //5

为什么又不能被修改了呢?

Object.create(xx.prototype)

就得到了xx的对象

属性的查询和设置

通过 . 号和 [] 和获取属性的值

对象可以看所是一个关联数组

但是值的注意的是 属性的名字最好不为数字。。

删除属性

delete 对象.属性
但是这个delete操作符只能删除自有 的属性,删除不了对象(类)从其他对象(类)继承来的属性

    function inherit(p) {
        if(p==null) throw TypeError();
        if(Object.create) {
            return Object.create(p);}
        var t=typeof p;
        if(t!="object"&&t!="function"){
            function F() {

            }
            f.prototype=p;
            return new F();
        }
    }
    var o={};
    o.x=1;
    var p=inherit(o);
    p.y=2;
    var q=inherit(p);
    q.cc=2;
    console.log(q.cc);   //2
    delete q.cc;
    console.log(q.cc);  //undefined
    console.log(q.x)   //1
    delete q.x;
    console.log(q.x)  //1

检测类中某个属性的存在

in 操作符

 function inherit(p) {
        if(p==null) throw TypeError();
        if(Object.create) {
            return Object.create(p);}
        var t=typeof p;
        if(t!="object"&&t!="function"){
            function F() {

            }
            f.prototype=p;
            return new F();
        }
    }
    function A() {
          this.x=1;
    }
    var a=new A();
    var p=inherit(a);
    p.y=2;
    var q=inherit(p);
    q.cc=2;
    console.log("cc" in q)  //true
    console.log("x" in q)  //true
    console.log("y" in q)  //true
    delete q.cc;
    console.log("cc" in q)  //false

对象(类).hasOwnProperty(“属性”)
检测某个属性是否为对象或者类的自有属性(不是继承来的)。

 function inherit(p) {
        if(p==null) throw TypeError();
        if(Object.create) {
            return Object.create(p);}
        var t=typeof p;
        if(t!="object"&&t!="function"){
            function F() {

            }
            f.prototype=p;
            return new F();
        }
    }
    function A() {
          this.x=1;
    }
    var a=new A();
    var p=inherit(a);
    p.y=2;
    var q=inherit(p);
    q.cc=2;
    console.log(q.hasOwnProperty("x"))  //false
    console.log(q.hasOwnProperty("cc"))  //true
    console.log(q.hasOwnProperty("y"))  //false

对象.propertyIsEnumerable (属性)
这个属性既是自身的属性也是可枚举的,但是toString这个方法就不是可枚举 的

 function inherit(p) {
        if(p==null) throw TypeError();
        if(Object.create) {
            return Object.create(p);}
        var t=typeof p;
        if(t!="object"&&t!="function"){
            function F() {

            }
            f.prototype=p;
            return new F();
        }
    }
    function A() {
          this.x=1;
    }
    var a=new A();
    var p=inherit(a);
    p.y=2;
    var q=inherit(p);
    q.cc=2;
    console.log(q.propertyIsEnumerable("x"))  //false
    console.log(q.propertyIsEnumerable("cc"))  //true
    console.log(q.propertyIsEnumerable("toString"))  //false

属性的可枚举性

for in循环
两个数组的合并,并去掉重复的

  var cc=[1,2,4,5,6];
    var dd=[1,2,7,8];
    function merge(p,q) {
        for(var i in q){
            if(q[i] in p) {
                continue;
            }
            p.push(q[i]);
        }
    }
    merge(dd,cc);
    console.log(cc);
    console.log(dd);

返回对象的所有的自有属性

   var cc={x:1};
     var dd=Object.create(cc);
     dd.y=1;
    console.log(Object.keys(dd)); //["y"]
    console.log(Object.keys(cc));  //["x"]

遍历

for of 用法

   var myArray=[1,2,3];
    for(var v of myArray){
        console.log(v);
    }

但是这种方法是能访问数组。不能为普通的对象直接使用for of来访问,只有给普通对象定义了Symbol.iterator属性之后,才可以通过for v来访问

这个遍历的访问过程:首先循环会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有返回值。利用的就是数组内置的iterator。
Symbol.iterator这个属性是ES6新出来的,作用就是获取数组的@@iterator内部属性。

     var myArray=[1,2,3];
    var it=myArray[Symbol.iterator]();
    console.log(it.next());  //Object {value: 1, done: false}
    console.log(it.next());   //Object {value: 2, done: false}
    console.log(it.next());   //Object {value: 3, done: false}
    console.log(it.next());   //Object {value: undefined, done: false}

done表示的是是否还有可以遍历的值。
但是普通的对象没有内置的@@iterator属性。

     var myObject={a:2,b:3};
    var it=myObject[Symbol.iterator]();
    console.log(it.next());   //myObject[Symbol.iterator] is not a function

Object.keys(myArray)这个方法是列出对象的所有的关键字。

     var myArray={a:2,b:3};
      console.log(Object.keys(myArray));   //["a","b"];

下面的这段代码实现的就是为普通的对象添加@@iterator属性

   var myObject={a:2,b:3};
     Object.defineProperty(myObject,Symbol.iterator,{
         enumerable:false,
         writable:false,
         configable:true,
         value:function () {   //定义了Symbol.iterator的值   值里边主要是返回了一个函数next()
             var o=this;
             var idex=0;
             var ks=Object.keys(o);
             return {
               next:function () {    //返回的next是一个函数 这个函数里边返回了valu和done两个值
                 return{
                     value:o[ks[idex++]],
                     done:(idex>ks.length)
                 }
               }
             }
         }
     })
    var it=myObject[Symbol.iterator]();
    console.log(it.next());   //Object {value: 2, done: false}
    console.log(it.next());   //Object {value: 3, done: false}
    console.log(it.next());   //Object {value: undefined, done: true}

在定义Symbol.iterator了之后通过for v来遍历对象

var myObject={a:2,b:3};
     Object.defineProperty(myObject,Symbol.iterator,{
         enumerable:false,
         writable:false,
         configable:true,
         value:function () {   //定义了Symbol.iterator的值   值里边主要是返回了一个函数next()
             var o=this;
             var idex=0;
             var ks=Object.keys(o);
             return {
               next:function () {    //返回的next是一个函数 这个函数里边返回了valu和done两个值
                 return{
                     value:o[ks[idex++]],
                     done:(idex>ks.length)
                 }
               }
             }
         }
     })
    for(v of myObject){
        console.log(v);   //2   3
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值