5.26复习,对象深入

普通函数和构造函数的区别

1、普通函数本质是与构造函数没有什么区别的。构造函数也是普通函数。创建方式两者一摸一样。在命名上构造函数的首字母一般要大写。
2、两者的调用方式不一样,普通函数直接调用,构造函数要使用new关键字来调用
3、new关键字作用:现创建了一个新的对象实例,将构造函数中的作用域指向这个新的对象。执行函数中的代码,将这个对象返回出去。
4、普通的函数一般没有返回值,为undefined。
5、普通函数,在调用时使用了new关键字,会正常执行,但是如果函数内部没有return,或者是return了一个基本数据类型,则返回一个空的对象。如果是构造函数中返回了一个基本数据类型,则会被创建的实例对象替换掉返回结果,如果返回了一个引用类型的数据,那么返回结果就是return的数据。
6、总的来说只要使用了new关键字,无论是不是构造函数,都会返回一个新的对象,区别就在于如果return了一个基本类型的数据,会被new创建的对象顶替掉,如果返回一个引用数据类型那么就会正常返回这个结果。

创建对象

创建对象一般有三种方式
1、字面量创建

  var obj1 = {
            uname: '张美丽',
            age: 18,
            sayHi: function() {
                console.log('nihao');

            }
        };

2、使用new关键字和Object对象

 var obj2 = new Object();
        obj2.uname = '李红';
        obj2['age'] = 19;
        obj2.sayHi = function() {
            console.log('你好');

        };

这里的new如果没有写,效果是一样的,但是为了标准,都要加上。
3、使用构造函数的创建方式

 function Person(uname, age) {
            this.uname = uname;
            this.age = age;
            this.sayHi = function(arg) {
                console.log('我说' + arg);

            }
        };
        var p1 = new Person('张三', 18);
        p1.sayHi('你真棒');

== 注意,使用构造函数创建的对象会在打印时前面带有构造函数的名字==

对象的遍历方法

对象的遍历方法有三种
1、使用for in遍历对象的属性

for (const key in obj) {
   console.log(key);
  }

这个方法会将对象中所有的属性遍历出来。包括其原型链上可以被枚举的属性。

2、使用Object.keys(),

 var keys = Object.keys(obj);//返回一个由对象可枚举属性组成的数组

这个方法返回的是一个由可枚举的自身属性组成的数组。通过遍历这个数组就可以对对象进行遍历。

3、使用Object.getOwnPropertyNames()

 Object.getOwnPropertyNames(obj).forEach(function (k,index) {
      console.log(k);
      console.log(index);
    })

这个方法它会返回一个所有自身属性组成的数组,包括不可枚举属性。

检查对象的属性是否存在

有两种方法
1、使用 in 操作符

 var obj1 = {
            name: '杨家乐',
        };


        // 使用 in 操作符检查属性是否存在
        console.log('name' in obj1); // true
        console.log('age' in obj1);  // false

2、使用obj.hasOwnproperty()方法检查是否具有属性

 // 使用 hasOwnProperty() 方法检查属性是否存在
        console.log(obj1.hasOwnProperty('name'));  // true
        console.log(obj1.hasOwnProperty('age'));  // false

== 注意hasOwnProperty()只能在对象自身的范围中寻找属性,而in操作符不仅在自身寻找,而且还会在对象的原型上寻找。不够严谨。==

属性的分类

对象的属性分为数据属性与访问器属性。

1、 数据属性,属性里面保存着基本数据。它包含的是一个数据值的位置,在这可以对数据值进行读写。

var obj1 = {
            firstName: '赵四',
            lastName: '尼古拉斯',
}

保存着一些基本的数据类型。
2、访问器属性:这个属性不包含数据值,包含的是一对get和set的方法,在读写访问器属性时,就是通过这两个方法来进行操作进行的。

  var obj1 = {
            // 数据属性
            uname: 'zhangsan',
            age: 18,
            // 访问器属性
            // sexx: '男',
            set gender(sex) {
                this.sexx = sex;
            },
            get gender() {
                return this.sexx;
            }

        };

当使用访问器属性访问和使用方法与正常写法一样,但是set方法里面必须有一个参数,不然会报错。当使用 . 来访问属性名时(gender)会调用get的方法,当给属性设置值时(用=赋值)会调用set的方法。

访问器属性的名字不能和对象已有属性进行重复,不然会造成栈溢出

数据特性,内部特性。

对象中的每一个属性都有自己的数据特性,这些特性决定了数据能否被修改,遍历,删除等。

1、configurable:这个表示属性能否被delete关键字进行删除,能否修改属性的特性,或者能够把属性修改为访问器属性。
2、enumerable:表示属性能否通过for-in循环遍历返回属性
3、writable:表示能否修改属性的值
4、value:表示该属性的数据值,默认是undefined。

以上属性中,布尔类型的默认值都是false,值类型的默认值都是undefined

获取查看对象的数据特性

使用Object.getOwnPropertyDescriptor()方法来获取对象的某条属性的数据特性。参数有两个,第一个是要获得的对象,第二个是要获得对象的属性。

 var obj = {
      // 数据属性
      name:'张浩',
      age:18,
      // 访问器属性
      get fullName(){
        return this.name;
      },
      set fullName(name){
        this.name = name;
      }
    }
    console.log(Object.getOwnPropertyDescriptor(obj,'name'));
// configurable: true
// enumerable: true
// value: "张浩"
// writable: true

使用Object.getOwnPropertyDescriptors()获取对象的所有属性的数据特性。参数只有一个,就是想要获取的对象。

 var obj = {
      // 数据属性
      name:'张浩',
      age:18,
      // 访问器属性
      get fullName(){
        return this.name;
      },
      set fullName(name){
        this.name = name;
      }
    }
  console.log(Object.getOwnPropertyDescriptors(obj));
 age: {value: 18, writable: true, enumerable: true, configurable: true}
fullName: {enumerable: true, configurable: true, get: ƒ, set: ƒ}
name: {value: "张浩", writable: true, enumerable: true, configurable: true}

这些只是能够获取这些值,不能够修改,接下来使用一些方法来对对象属性的数据特性进行修改

**修改对象内部的数据特性 **
可以使用Object.defineProperty()对对象的某一个属性进行数据特性修改它所接受的参数有三个,第一个要修改的对象,第二个要进行修改的属性字符串形式,第三个是一个对象,里面写着要修改的内容

 var obj = {
        name:'张浩',
        age: 18,
      }
      Object.defineProperty(obj,'name',{
        configurable:true,
        enumerable:false,
        writable:true
      });
      console.log(obj);
      

这样一个一个修改效率肯定不行,我们可以使用Object.definePreperties()方法来一次性对对象的多个属性进行修改。

  Object.defineProperties(obj, {
      name: {
        enumerable:false,
        configurable:true,
        writable:true
      },
      gender: {
        enumerable:false,
        configurable:true,
        writable:true,
        get: function () {
          return this.name
        },
        set: function (e) {
          this.name = e;
        }
      }
    })

Object.definePreperties()不仅可以修改,还能创建一个新的对象,用法如下:给一个空的对象直接定义它内部特性。

 var obj2 = Object.defineProperties({},{
      name:{
        value:'张浩',
      },
      fullNmae:{
        get:function(){
          return this.name;
        },
        set:function(newName){
          this.name = newName;
        }
      }
    })
    console.log(obj2);

这样返回的对象中如果没有设置特性值,默认会为false和undefined。

禁止扩展

对象也有和属性一样类似的特性如[[Extensible]],它指明了对象本身是否可扩展的修改,默认情况下对象都是可以扩展的,随时都可以对象添加新的属性。如果设置了[[Extensible]]值为false,就能禁止对象添加新的属性。三种禁止扩展的方法。
1、Object.preventExtensions()将对象变成不可扩展的对象,这个方法接受一个参数,就是被修改的对象。对象被禁止扩展后就不能进行新属性的添加了。

   name:'张浩',
      age:18,
      gender:'男'
    };
    // 1.禁止扩展(对象不能添加新的属性,但是可以删除,和修改,枚举。)
    Object.preventExtensions(obj);
    console.log(Object.isExtensible(obj));//true
    console.log(obj);

2、Object.seal()封印对象,被封印的对象不能够被添加新的属性,不能删除,可以修改,可以枚举。

 Object.seal(obj);
    obj.sex = 1;//不能添加
    delete obj.name;//不能删除
    obj.name = '张三';//不能修改
    console.log(obj);
    console.log(Object.isSealed(obj));// true
    console.log(Object.isExtensible(obj)); // false

3、Object.freeze()冻结对象,被冻结的对下个不能添加,修改,删除,可以枚举。就是说这个对象只能进行读取。

 Object.freeze(obj);
    obj.sex = 1;
    delete obj.name;
    obj.name = '张三';
    console.log(obj);
    console.log(Object.isFrozen(obj));// true
    console.log(Object.isSealed(obj));// true
    console.log(Object.isExtensible(obj));// false

这个三个其实是逐级递增的。isExtensible是判断是否是可扩展的,为true时就代表它是可以扩展的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值