JS属性查找的规则

1、属性普通定义

// var a = "a";
// console.log(window.a)
// console.log(a)
//基本的属性定义形式
    var key = "wife";
    var key2 = "son";
    var obj = {
        name:"damu",
        [key2]:"小达姆"
    };
    obj.age = 18;
    obj[key]="冬雨";

    console.log(Object.getOwnPropertyDescriptor(obj,"name"))

2、属性数据描述符

  // writable;value;enumerable;configurable : 属性描述符

    var damu = {name:"达姆"};

    //wife 可以称为是 damu的数据描述符属性
    Object.defineProperty(damu,"wife",{
        writable:false, //当前这个属性的值是否可以修改
        value:"冬雨",   //当前这个属性的值
        enumerable:false,//当前这个属性是否可枚举(是否可以出现在对象的for in循环中)
        configurable:false//当前这个属性是否可配置(能不能重新定义 能不能删除)
    })
 //静默失败
    // damu.wife="老付";
    // delete damu.wife
 for(var key in damu){
        console.log(key);
    }
Object.defineProperty(damu,"wife",{
        writable:true, //当前这个属性的值是否可以修改
        value:"冬雨",   //当前这个属性的值
        enumerable:true,//当前这个属性是否可枚举(是否可以出现在对象的for in循环中)
        configurable:true//当前这个属性是否可配置(能不能重新定义 能不能删除)
    })

3、属性访问描述符

 // writable;value;enumerable;configurable : 属性描述符
 var damu = {
        name:"达姆",
        get age(){
          return this.__age__
        },
        set age(val){
          if (val<0){
              val = 0;
          }else if(val>150){
              val = 150;
          }
          this.__age__ = val
        }
    };

    var damu = {name:"达姆"}

    //age 可以称为是 damu的访问描述符属性
    Object.defineProperty(damu,"age",{
        // writable:false,
        // value:123,
        get:function () {
            return this.__age__
        },
        set:function (val) {
            if (val<0){
                val = 0;
            }else if(val>150){
                val = 150;
            }
            this.__age__ = val
        },
        enumerable:false,
        configurable:false
    })

    damu.age = 120000;
    console.log(damu.age);
    console.log(damu.__age__);

4、属性的存在性检查

var obj = {a:'a',b:'b'};

    //关键字可以访问原型链
    console.log("toString" in obj)
    //方法不可以访问原型链
    console.log(obj.hasOwnProperty("toString"))
    console.log(Object.getOwnPropertyNames(obj))

5、对象不变性
01、常量属性
Object.defineProperty

    var obj = {
        name:'老付'
    };

    Object.defineProperty(obj,"wife",{
        writable:false,
        value:"陪悦",
        configurable:false,
        enumerable:true
    })

    obj.wife2 = "小乐"
    obj.wife = "安妮"
    console.log(obj);

02、禁止对象扩展
Object.preventExtensions(obj)

    var obj = {name:'老付'};
    Object.preventExtensions(obj)

    obj.name="小老付"
    obj.wife="老张";
    delete obj.name
    console.log(obj);

03、密封对象
Object.seal(obj)

    var obj = {name:'老付'};
    Object.seal(obj)

    obj.name = "xxx"
    delete obj.name
    console.log(obj);

04、冻结对象
Object.freeze(obj)

  //方法不可以访问原型链 也影响不了对象的深层属性
    var obj = {
        name:'老付',
        wife:{
            name:"xxx"
        }
    };
    Object.freeze(obj)

    obj.wife = "陪悦";
    console.log(obj);

05、利用递归实现深度冻结对象属性


   var obj = {
       a:{
           b:{
               c:{
                   d:"d"
               }
           }
       },
       name:"xx"
   }

   //深度冻结
   Object.deepFreeze = function (obj) {
        var propNames = Object.getOwnPropertyNames(obj)
        propNames.forEach((item)=>{
            var val = obj[item];
            if(typeof val === "object" && val !==null){
                // 说明val肯定是对象
                Object.deepFreeze(val)
            }
        })
        //浅冻结
        Object.freeze(obj)
   }


   Object.deepFreeze(obj);
   obj.a.b.c.d="xxxx";
   console.log(obj);

6、原型&原型链
01、函数的定义

   // function add(a,b) {return a+b}
    // var add = function(a,b){return a+b}
    const add = new Function('a', 'b', 'return a + b');

    console.log(add(1, 2));

02、属性的设置

    // Object.prototype.a = "Object_prototype_a"
    Object.defineProperty( Object.prototype,"a",{
        // writable:false,
        // value:"a",
        enumerable:true,
        configurable:true,
        set:function (val) {        
        }
    })
    var obj = {};
    obj.a = "a";

    console.log(obj);

03、方法的重写


   // arr.__proto__ --> obj.__proto__ --> Array.prototype.__proto__ --> Object.prototype.__proto__ -->null

    var obj = {toString:function () {return "冬雨 ❤ 达姆"}};
    obj.__proto__ = Array.prototype;
    var arr = ["老付","陪悦","安妮","小乐","丹丹"];
    arr.__proto__ = obj;
    console.log(arr.toString())


    // console.log(Object.prototype.toString.call(arr))

04、继承
04-1构造函数的继承

	
		function Person(age,name){
			this.age=age;
			this.name=name;
			this.eat=function(){
				console.log("吃很多")
			}
		}
		function Teacher(course,age,name){
			Person.call(this,age,name);
			this.course =course;
		}
		function Student(num,age,name){
			Person.call(this,age,name);
			this.num =num;
		}
		var damu = new Teacher("qkl",18,"达姆");
		damu.eat();
		var damu2 = new Student(1,18,"达姆");
		damu2.eat();
		console.log(damu,damu2);

04-2原型链继承

Person.prototype.eat=function(){
			console.log("吃很多")
		}
		function Person(age,name){
			this.age=age;
			this.name=name;
		}

		Teacher.prototype = new Person();
		/*Teacher.prototype.constructor = Teacher;
		console.log(Teacher.prototype.constructor);*/
		function Teacher(course,age,name){
			this.course =course;
		}
		
		Student.prototype = new Person();
		function Student(num,age,name){
			this.num =num;
		}
		var damu = new Teacher("qkl",18,"达姆");
		var damu2 = new Student(1,18,"达姆");
		damu.eat();
		damu2.eat();
		console.log(damu,damu2);
		console.log(damu.constructor);
		

04-3组合继承


		/*
		 js中的原型链继承只有一个目的
			降低创建对象的开销!!!
		*/
	
		Person.prototype.eat=function(){
			console.log("吃很多")
		}
		function Person(age,name){
			this.age=age;
			this.name=name;
		}
		
		Teacher.prototype = new Person();
		Teacher.prototype.constructor = Teacher;
		console.log(Teacher.prototype.constructor);
		function Teacher(course,age,name){
			Person.call(this,age,name);
			this.course =course;
		}
		
		Student.prototype = new Person();
		function Student(num,age,name){
			Person.call(this,age,name);
			this.num =num;
		}

		var damu = new Teacher("qkl",18,"达姆");
		var damu2 = new Student(1,18,"达姆");
		damu.eat();
		damu2.eat();
		console.log(damu,damu2);
		console.log(damu.constructor);

04-4对象级别的继承

		var father={name:"马云"};
		var son = Object.create(father)
		debugger

7、笔记

原型&原型链

显示原型: 所有的函数都有显示原型(可以认为显示原型是一个Object类型的对象)
隐式原型: 所有的对象都有隐式原型
对象的隐式原型指向其构造函数的显示原型
原型链是隐式原型链
原型链的头是 Object.prototype.__proto__

属性查找与设置规范

属性查找:
    找obj.a; 先在obj中的直接属性内找;如果找到则使用找到的值;如果没有找到;上原型链
    如果整条原型链都没有对应的属性 则返回undefined

属性设置
    obj.a = 'a' ; 无论如何改动的都是obj对象;如果obj没有a属性则设置一个;如果obj有a属性则修改
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值