js- 面向对象进阶

简介: Object.defineProperty等面向对象的信息

对象详解

Object.defineProperty

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

    • obj : 要定义属性的对象。
    • prop : 要定义或修改的属性的名称。
    • descriptor : 要定义或修改的属性描述符。
  2. 对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。

  3. 数据描述符:

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

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

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

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

  4. 存取描述符 不能和writable 和value 权限同时使用

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

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

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

      var obj = {
             
          _year : 2022
      }
      Object.defineProperty(obj,'year',{
             
          get : function(){
             
              return this._year;
          },
          set : function(yyyy){
             
              if(yyyy > 2022){
             
                  this._year = yyyy;
              }
          }
      })
      obj.year = 2023;
      console.log(obj._year);
      
  1. 定义多个属性

    var student = {
         };
    var obj = {
         };
    Object.defineProperties(student,{
         
        name: {
         
            writeble : false,
            value: "张三"
        },
        age : {
         
            writeble: true,
            value: 16
        },
        sex: {
         
            get(){
         
                return '男';
            },
            set(v){
         
                obj.sex = v;
            }
        }
    })
    obj.sex = '男';
    console.log(student.name + ':' + student.age); //张三:16
    console.log(obj.sex); //男
    student.sex = '女';
    console.log(student.sex); //男
    console.log(obj.sex); //女
    

Proxy

  1. 概念:

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

  1. 语法:

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

  • new Proxy()表示生成一个Proxy实例

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

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

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

    let obj = {
         name: '张三',age: 18};
    //开始代理
    let result = new Proxy(obj,{
         
        //配置get来进行代理设置
        get(target,property){
         
            //target: 就是你要代理的目标对象,我们当前是obj
            //property: 就是该对象内的每一个属性,自动遍历
            return target[property];
        },
        //配置set来进行修改
        set(target,property,value){
         
            //target: 就是你要代理的目标对象,我们当前是obj
            //property: 就是该对象内的你要修改的那个属性
            //value: 就是你要修改的那个属性的值
            target[property] = value;
    
            console.log('你在修改' + property + '属性,你想修改为:' + value);
            //注意:简单代理需要返回 true
            return true;
        }
    })
    console.log('原始数据:' + obj);
    console.log('代理结果:' + result);
    console.log('代理结果 name : ' + result.name);
    
    //尝试修改
    result.name = '李四';
    console.log('代理结果 name: ' + result .name);
    
    //动态插入
    result.sex = '男';
    console.log('代理结果 sex:' + result.sex);
    

hasOwnProperty

hasOwnProperty : 表示是否有自己的属性。这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链。

let obj = {
   
    a : 1,
    fn : function(){
   },
    c : {
   
        d : 2
    }
}
console.log(obj.hasOwnProperty('a')); //true
console.log(obj.hasOwnProperty('fn')); //true
console.log(obj.hasOwnProperty('c')); //true
console.log(obj.c.hasOwnProperty('d')); //true
console.log(obj.hasOwnProperty('d')); //false

let str = new String();
console.log(str.hasOwnProperty('charAt')); //false
console.log(String.prototype.hasOwnProperty('charAt')); //true

判断自身属性是否存在

let obj = new Object(); //创建一个空对象
obj.name = '张三'; //添加一个name属性
//备份一份旧的name属性,然后删除旧属性
function changeObj(){
   
    obj.newname = obj.name;
    delete obj.name;
}
console.log(obj.hasOwnProperty('name')); //true
changeObj();
console.log(obj.hasOwnProperty('name')); //false

判断自身属性与继承属性

function foo() {
   
    this.name = 'foo'
    this.sayHi = function () {
   
        console.log('Say Hi')
    }
}

foo.prototype.sayGoodBy = function () {
   
    console.log('Say Good By')
}

let myPro = new foo()

console.log(myPro.name) // foo
console.log(myPro.hasOwnProperty('name')) // true
console.log(myPro.hasOwnProperty('toString')) // false
console.log(myPro.hasOwnProperty('hasOwnProperty')) // false
console.log(myPro.hasOwnProperty('sayHi')) // true
console.log(myPro.hasOwnProperty('sayGoodBy')) // false
console.log('sayGoodBy' in myPro) // true

遍历一个对象的所有自身属性:使用hasOwnProperty()方法来忽略继承属性。

var buz = {
   
    a: 1
};

for (var name in buz) {
   
    if (buz.hasOwnProperty(name)) {
   
        alert(name + ':' + buz[name]);
    }
    else {
   
        alert(name); 
    }
}
相关文章
|
6月前
|
前端开发 JavaScript 开发者
JavaScript进阶-Promise与异步编程
【6月更文挑战第20天】JavaScript的Promise简化了异步操作,从ES6开始成为标准。Promise有三种状态:pending、fulfilled和rejected。基本用法涉及构造函数和`.then`处理结果,如: ```javascript new Promise((resolve, reject) => { setTimeout(resolve, 2000, '成功'); }).then(console.log); // 输出: 成功
99 4
|
6月前
|
存储 JavaScript 前端开发
JavaScript进阶-Map与Set集合
【6月更文挑战第20天】JavaScript的ES6引入了`Map`和`Set`,它们是高效处理集合数据的工具。`Map`允许任何类型的键,提供唯一键值对;`Set`存储唯一值。使用`Map`时,注意键可以非字符串,用`has`检查键存在。`Set`常用于数组去重,如`[...new Set(array)]`。了解它们的高级应用,如结构转换和高效查询,能提升代码质量。别忘了`WeakMap`用于弱引用键,防止内存泄漏。实践使用以加深理解。
85 3
|
5月前
|
XML 前端开发 JavaScript
JavaScript进阶 - AJAX请求与Fetch API
【7月更文挑战第3天】前端开发中的异步基石:AJAX与Fetch。AJAX,使用XMLHttpRequest,处理跨域、回调地狱和错误处理。Fetch,基于Promise,简化请求,但需注意默认无跨域头和HTTP错误处理。两者各有优劣,理解其问题与解决策略,能提升前端应用的性能和用户体验。
169 24
|
6月前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
155 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
5月前
|
前端开发 JavaScript 安全
JavaScript进阶-JavaScript库与框架简介
【7月更文挑战第11天】JavaScript库和框架加速Web开发,但也带来挑战。选择适合项目、团队技能的库或框架,如React、Angular、Vue,是关键。保持依赖更新,注意性能优化,避免过度依赖。遵循最佳实践,确保安全性,如防XSS和CSRF。学习基础,结合代码示例(如React计数器组件),提升开发效率和应用质量。
71 1
|
5月前
|
缓存 JavaScript 前端开发
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第4天】JavaScript的Web Workers和Service Worker增强了Web性能。Web Workers处理后台多线程,减轻主线程负担,但通信有开销,受同源策略限制。Service Worker则用于离线缓存和推送通知,需管理其生命周期、更新策略,并确保安全。两者都带来了挑战,但也极大提升了用户体验。通过理解和优化,开发者能构建更高效、安全的Web应用。
146 2
|
5月前
|
资源调度 JavaScript 前端开发
JavaScript进阶 - JavaScript库与框架简介
【7月更文挑战第5天】JavaScript库和框架构成了前端开发的核心,如jQuery简化DOM操作,Angular、React和Vue提供全面解决方案。选择时要明确需求,避免过度工程化和陡峭学习曲线。使用版本管理工具确保兼容性,持续学习以适应技术变化。示例展示了jQuery和React的简单应用。正确选择和使用这些工具,能提升开发效率并创造优秀Web应用。
56 2
|
5月前
|
设计模式 前端开发 JavaScript
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第1天】JavaScript设计模式增进代码复用和维护性。单例模式确保唯一实例,用闭包防止命名冲突和控制状态访问。观察者模式实现一对多依赖,通过解绑避免内存泄漏。工厂模式封装对象创建,适度使用避免复杂度。装饰者模式动态添加行为,保持简洁以保可读性。理解模式的优缺点,灵活应用,提升代码质量。
132 3
|
5月前
|
存储 前端开发 安全
JavaScript进阶 - 浏览器存储:localStorage, sessionStorage, cookies
【7月更文挑战第2天】探索Web存储:localStorage持久化,sessionStorage会话限定,cookies则伴随HTTP请求。了解它们的特性和限制,如localStorage的5MB容量限制、跨域问题,sessionStorage的生命周期,及cookies的安全与带宽消耗。使用时需权衡安全、效率与应用场景。示例代码展示存储与检索方法。
360 2
|
6月前
|
JavaScript 前端开发
JavaScript进阶-Class与模块化编程
【6月更文挑战第21天】**ES6引入Class和模块化,提升JavaScript的代码组织和复用。Class是原型机制的语法糖,简化面向对象编程。模块化通过`import/export`管理代码,支持默认和命名导出。常见问题包括`this`指向和循环依赖。理解这些问题及避免策略,能助你写出更高效、可维护的代码。**
67 5