javascript中的原型和原型链&set和map&object.defineProperty和Proxy&object中的方法属性

一.原型

     原型: 原型也叫作“原型对象”,任何一个js对象都有与之对应的原型

     获取对象的原型:对象 _proto_

      比如构造函数Tank,new一个实例对象t,求实例对象t的原型:t._proto_得到{constructor...}

对于对象{constructor...}再对它constructor,得到构造函数Tank,而对构造函数Tank求原型对象得到{constructor...},所以我们可以得到以下关系:

     对象._proto_==函数.prototype

     对象._proto_.constructor==函数

     对象._proto_.constructor=函数.prototype.constructor

     获取对象原型:函数.prototype

 二.原型链

          通过对象的__proto__属性一级一级向上查找得到一个有_proto_构成的链条,这个链条就是原型链。

          原型链的终点是object的原型

          Object是所有对象的顶层构造函数,即所有的对象都可以看做是由Object创建的

          instanceof用来判断一个实例对象是否是构造函数的实例

三.set以及set的应用

   set的应用:

<script>
        //Set中数据不会重复
        var s = new Set([1,2,3,4,5,6])
        s.add(1); //添加元素到 set,1存在添加不上
        //s.delete(3); //从set删除元素,
        if( s.has(2) ){  //判断某个元素是否在set中
            console.log('2存在');
        }
        s.forEach((item,index)=>{
            console.log(item,index);
        })
        // s.clear(); //清空 set
        console.log(s);
        console.log(s.size);
</script>

  set去重:

       //数组去重
        var arr = [1,2,3,4,4,3,2,1];
        //写法一
        var s = [...new Set(arr)];
        console.log(s);
        
        //写法二
        var s = Array.from( new Set(arr) )
        console.log(s);

  Map:

    <script>
        //Map是种数据结构,类似对象
        var m = new Map();
        m.set('name','李煜'); 
        //向map结构 添加数据
        m.set('age',30);
        m.set('sex',false);
        console.log( m.get('name') , m.get('age') , m.get('sex') );
        //从map结构中获取数据
        console.log( m.has('age') );
        m.forEach((item,key)=>{
            console.log(item,key);
        })
        console.log(m);
    </script>

4.object.defineProperty和Proxy

      区别:defineproPerty是对属性的劫持,给对象的某个属性进行监听。proxy是对整个对象的代理,如果需要监听某一个对象的所有属性,需要遍历对象所有属性并对其进行劫持来进行监听。

defineProperty:无法监听对象新增属性,proxy可以;

defineProperty无法监听对象的删除属性,proxy可以;

defineProperty不能监听数组下标改变值的变化,proxy可以且不需要对数组方法进行重载;

defineProperty是循环遍历对象属性的方式来进行监听,自然会比proxy对整个对象进行监听的方式要消耗性能。

 var obj = { name:'李煜',age:30, father:{ name:'',age:90, son:{name:'',age:10} } };
        //writable 对象的属性是否可修改 ( 修改值 )
        //configurable 对象的属性是否可操作 ( 删除 )
        //enumerable 对象的属性是否可枚举 ( 遍历 )

        Object.defineProperty(obj, 'name', { writable:true })
        Object.defineProperty(obj, 'name', { configurable:true })
        Object.defineProperty(obj, 'name', { enumerable:true })
        Object.defineProperty(obj, 'name', { 
            // writable:true,
            set: function( newValue ){ 
            //在set函数中不能 执行针对该属性的赋值操作,会导致函数的递归调用.
                console.log('修改了name属性的值',newValue); 
            },
            get: function(){ 
            //在get函数中不能 执行获取该属性的操作, 会导致函数的递归调用.
                console.log('获取了name属性的值');
                return '李煜'+'!!!';
            },
        })
 var obj = { name:'李煜',age:30, father:{ name:'',age:90, son:{name:'',age:10} } };
 //监听对象的所有属性
        //思路:
        //1.先用for in 遍历对象, 拿到对象的每个属性
        //2.用Object.defineProperty给对象的每个属性设置监听

        //作用: 传入一个对象, 对该对象的每个属性进行遍历并且监听.
        function listenObj(obj){
            for(var key in obj){
                if( typeof obj[key] == 'object' ){ 
        //如果某个属性是引用类型, 则递归遍历该属性
                    listenObj(obj[key]) //递归遍历该属性
                }else{ //不是引用类型
                    Object.defineProperty(obj, key , {
                        set:()=>{ console.log('修改了属性的值');  },
                        get:()=>{ console.log('获取了属性的值'); }
                    })
                }
            }
        }

        listenObj(obj)

 5.object中的方法属性

         注意:当调用对象的某个方法时, 首先在对象自身找该方法,如果自身有该方法则调用成功,如果没有则继续沿着由__proto__构成的原型链查找该方法, 如果一直到原型链的终点都没有找到则报错.

 以下为存在于Object中的,是可以找见的方法:

        Object.prototype.constructor

        Object.prototype.toString()

        Object.prototype.toLocaleString()

        Object.prototype.hasOwnProperty()

        Object.prototype.isPrototypeOf()

  判断一个属性是否在对象身上:

        hasOwnProperty() 在判断一个属性是否在对象身上时, 不会沿着原型链查找的(只会在对象自身身上查找。)

var obj = { name:'李煜',age:30 }
if( obj.hasOwnProperty('toString') ){
        // if( 'toString' in obj ){
            console.log('在obj身上');
        }else{
            console.log('不在obj身上');
        }
//输出不在

        in 在判断一个属性是否在对象身上时, 会沿着原型链查找

        isPrototypeOf() 判断一个对象 是否是某个函数的原型对象

        结论: js中任何一个对象都可以看做是 Object这个顶层构造函数的实例对象、

       if( Array.prototype.isPrototypeOf( Object ) ){
            console.log('是');
        }else{
            console.log('不是');      
        }
       //打印结果为不是,因为object的原型对象为null

       if( Object.prototype.isPrototypeOf( RegExp ) ){
         console.log('是');
        }else{
            console.log('不是');      
        }
       //打印结果为是,因为js中任何一个对象都可以看做是 Object这个顶层构造函数的实例对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值