• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

JS入门到精通 对象和深浅拷贝面试题15

武飞扬头像
zxpmoxo
帮助1

对象详解

Object.defineProperty

  1. Object.defineProperty(obj, prop, descriptor) 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

  • obj : 要定义属性的对象。

  • prop : 要定义或修改的属性的名称。

  • descriptor : 要定义或修改的属性描述符。

  1. 对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。

  1. 数据描述符:

  • configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false。

  1.  
    var obj = {
  2.  
    name : "张三"
  3.  
    }
  4.  
    Object.defineProperty(obj,"name",{
  5.  
    configurable : false
  6.  
    })
  7.  
    console.log(obj); //{name : "张三"}
  8.  
    delete obj.name;
  9.  
    console.log(obj); //{name : "张三"}
  • enumerable:表示能否通过for in循环访问属性,默认值为false

  • writable:表示能否修改属性的值。默认值为false。

  1.  
    var obj = {
  2.  
    name : "张三"
  3.  
    }
  4.  
    Object.defineProperty(obj,'age',{
  5.  
    writable : false,
  6.  
    value : 18
  7.  
    })
  8.  
    console.log(obj.age); //18
  9.  
    obj.age = 20;
  10.  
    console.log(obj.age); //18
  • value:包含这个属性的数据值。默认值为undefined。

  1. 存取描述符

  • get:getter在读取属性时调用的函数,默认值是undefined

  • set:setter在写入属性的时候调用的函数,默认值是undefined

  • : setter 不能和writable 、value 一起使用。不然报错。

  1.  
    var obj = {
  2.  
    _year : 2022
  3.  
    }
  4.  
    Object.defineProperty(obj,'year',{
  5.  
    get : function(){
  6.  
    return this._year;
  7.  
    },
  8.  
    set : function(yyyy){
  9.  
    if(yyyy > 2022){
  10.  
    this._year = yyyy;
  11.  
    }
  12.  
    }
  13.  
    })
  14.  
    obj.year = 2023;
  15.  
    console.log(obj._year);
学新通
  1. 定义多个属性

  1.  
    var student = {};
  2.  
    var obj = {};
  3.  
    Object.defineProperties(student,{
  4.  
    name: {
  5.  
    writeble : false,
  6.  
    value: "张三"
  7.  
    },
  8.  
    age : {
  9.  
    writeble: true,
  10.  
    value: 16
  11.  
    },
  12.  
    sex: {
  13.  
    get(){
  14.  
    return '男';
  15.  
    },
  16.  
    set(v){
  17.  
    obj.sex = v;
  18.  
    }
  19.  
    }
  20.  
    })
  21.  
    obj.sex = '男';
  22.  
    console.log(student.name ':' student.age); //张三:16
  23.  
    console.log(obj.sex); //男
  24.  
    student.sex = '女';
  25.  
    console.log(student.sex); //男
  26.  
    console.log(obj.sex); //女
学新通

Proxy

  1. 概念:

Proxy : ES6提供的数据代理,表示由它来“代理”某些操作,可以称为“代理器"
  1. 语法:

new Proxy(代理原始对象,{配置项}) : 返回的实例对象,就是代理结果数据
  • new Proxy()表示生成一个Proxy实例

  • 代理原始对象: 要被代理的对象,可以是一个object或者function

  • 配置项:也是一个对象,对该代理对象的各种操作行为处理。

  • Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

  1.  
    let obj = {name: '张三',age: 18};
  2.  
    //开始代理
  3.  
    let result = new Proxy(obj,{
  4.  
    //配置get来进行代理设置
  5.  
    get(target,property){
  6.  
    //target: 就是你要代理的目标对象,我们当前是obj
  7.  
    //property: 就是该对象内的每一个属性,自动遍历
  8.  
    return target[property];
  9.  
    },
  10.  
    //配置set来进行修改
  11.  
    set(target,property,val){
  12.  
    //target: 就是你要代理的目标对象,我们当前是obj
  13.  
    //property: 就是该对象内的你要修改的那个属性
  14.  
    //val: 就是你要修改的那个属性的值
  15.  
    target[property] = val;
  16.  
    console.log('你在修改' property '属性,你想修改为:' val);
  17.  
    //注意:简单代理需要返回 true
  18.  
    return true;
  19.  
    }
  20.  
    })
  21.  
    console.log('原始数据:' obj);
  22.  
    console.log('代理结果:' result);
  23.  
    console.log('代理结果 name : ' result.name);
  24.  
     
  25.  
    //尝试修改
  26.  
    result.name = '李四';
  27.  
    console.log('代理结果 name: ' result .name);
  28.  
     
  29.  
    //动态插入
  30.  
    result.sex = '男';
  31.  
    console.log('代理结果 sex:' result.sex);
学新通

hasOwnProperty(相当于===)

in相当于(==)

hasOwnProperty : 表示是否有自己的属性。这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链。
  1.  
    let obj = {
  2.  
    a : 1,
  3.  
    fn : function(){},
  4.  
    c : {
  5.  
    d : 2
  6.  
    }
  7.  
    }
  8.  
    console.log(obj.hasOwnProperty('a')); //true
  9.  
    console.log(obj.hasOwnProperty('fn')); //true
  10.  
    console.log(obj.hasOwnProperty('c')); //true
  11.  
    console.log(obj.c.hasOwnProperty('d')); //true
  12.  
    console.log(obj.hasOwnProperty('d')); //false
  13.  
     
  14.  
    let str = new String();
  15.  
    console.log(str.hasOwnProperty('charAt')); //false
  16.  
    console.log(String.prototype.hasOwnProperty('charAt')); //true
学新通
判断自身属性是否存在
  1.  
    let obj = new Object(); //创建一个空对象
  2.  
    obj.name = '张三'; //添加一个name属性
  3.  
    //备份一份旧的name属性,然后删除旧属性
  4.  
    function changeObj(){
  5.  
    obj.newname = obj.name;
  6.  
    delete obj.name;
  7.  
    }
  8.  
    console.log(obj.hasOwnProperty('name')); //true
  9.  
    changeObj();
  10.  
    console.log(obj.hasOwnProperty('name')); //false
判断自身属性与继承属性
  1.  
    function foo() {
  2.  
    this.name = 'foo'
  3.  
    this.sayHi = function () {
  4.  
    console.log('Say Hi')
  5.  
    }
  6.  
    }
  7.  
     
  8.  
    foo.prototype.sayGoodBy = function () {
  9.  
    console.log('Say Good By')
  10.  
    }
  11.  
     
  12.  
    let myPro = new foo()
  13.  
     
  14.  
    console.log(myPro.name) // foo
  15.  
    console.log(myPro.hasOwnProperty('name')) // true
  16.  
    console.log(myPro.hasOwnProperty('toString')) // false
  17.  
    console.log(myPro.hasOwnProperty('hasOwnProperty')) // false
  18.  
    console.log(myPro.hasOwnProperty('sayHi')) // true
  19.  
    console.log(myPro.hasOwnProperty('sayGoodBy')) // false
  20.  
    console.log('sayGoodBy' in myPro) // true
学新通
遍历一个对象的所有自身属性:使用hasOwnProperty()方法来忽略继承属性。
  1.  
    var buz = {
  2.  
    a: 1
  3.  
    };
  4.  
     
  5.  
    for (var name in buz) {
  6.  
    if (buz.hasOwnProperty(name)) {
  7.  
    alert(name ':' buz[name]);
  8.  
    }
  9.  
    else {
  10.  
    alert(name);
  11.  
    }
  12.  
    }

浅拷贝(面试题)

针对引用类型而言,浅拷贝指的是复制对象的引用,即直接给引用类型赋值,如果拷贝后的对象发生变化,原对象也会发生变化。而深拷贝是真正地对对象进行拷贝,修改拷贝后的新对象并不会对原对象产生任何影响。
在JS中数据类型分为基本类型和引用类型 基本类型: number, boolean,string,symbol,undefined,null
引用类型:object 以及一些标准内置对象 Array、RegExp、String、Map、Set..

基本类型数据拷贝(值拷贝)

基本类型数据都是值类型,存储在栈内存中,每次赋值都是一次复制的过程
  1.  
    var a = 12;
  2.  
    var b = a;
  3.  
    console.log(a,b); //12 12
  4.  
    a = 13;
  5.  
    console.log(a,b); //13 12

引用类型数据拷贝

只拷贝对象的一层数据,再深处层次的引用类型value将只会拷贝引用

浅拷贝

//浅拷贝的特点:

//1. 拷贝的是对象的引用地址

//2. 当我修改一个对象中的属性时,两个对象中的属性会同时改变。

  1.  
    let obj = {
  2.  
    a : 1,
  3.  
    b : {
  4.  
    c : 2,
  5.  
    d : {
  6.  
    f : 3
  7.  
    }
  8.  
    }
  9.  
    }
  10.  
    let newObj = {... obj};
  11.  
    console.log(newObj);
  12.  
    obj.b.c = 10;
  13.  
    console.log(newObj);
  1.  
    function cloneObj(obj){
  2.  
    let clone = {};
  3.  
    for(let key in obj){
  4.  
    clone[key] = obj[key];
  5.  
    }
  6.  
    return clone;
  7.  
    }
  8.  
    let a = {
  9.  
    x : {
  10.  
    y : 1
  11.  
    }
  12.  
    }
  13.  
    let b = cloneObj(a);
  14.  
    console.log(a,b);

深拷贝

深拷贝就不会像浅拷贝那样只拷贝一层,而是有多少层我就拷贝多少层,要真正的做到全部内容都放在自己新开辟的内存里。可以利用递归思想实现深拷贝。
  1.  
    function cloneObj(obj) {
  2.  
    let clone = {};
  3.  
    for (let i in obj) {
  4.  
    // 如果为对象则递归更进一层去拷贝
  5.  
    if (typeof obj[i] == "object" && obj[i] != null) {
  6.  
    clone[i] = cloneObj(obj[i]);
  7.  
    } else {
  8.  
    clone[i] = obj[i];
  9.  
    }
  10.  
    }
  11.  
    return clone;
  12.  
    }

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghfhig
系列文章
更多 icon
同类精品
更多 icon
继续加载