• 重温javascript --(三)对象


    对象

    一. 对象创建

    1. var a = {} 字面量创建

    2. 构造函数

    1. 系统构造函数Object()var per = new Object()

    2. 自定义构造函数

       function Person(name){
          this.name = name,
          this.age = 18
        }
        var person = new Person('limei')
      
      • 1
      • 2
      • 3
      • 4
      • 5

      new 关键字 会在构造函数内部:

      1. 隐性创建 var this ={};
      2. 赋值this.xxx = xxx;
      3. 最后隐性返回 return this;
    3. Object.create()方法:

    Object.create(proto, [propertiesObject])

    • proto:必需。新创建的对象的 __proto__
    • propertiesObject:可选。如果该参数是一个对象,那么其自有可枚举属性(即那些自有属性且其 enumerabletrue 的属性)的键值对会被添加到新创建对象的对应属性上,作为新创建对象的自有属性。这些属性的描述符由 propertiesObject 中对应属性的值提供。

    示例:

    // 1.
    const obj = Object.create(null) // obj 为 {}
    console.log(emptyObject.__proto__); // 输出:undefined
    
    // 2.
    const person = {
    	sex: '男',
    	say: function () {
    		console.log(`${this.name}说:我今年${this.age}了,我的性别是:${this.sex}`)
    	}
    }
    const xiaoMing = Object.create(person, {
    	// 定义一个数据描述符  
    	age: {  
    	    value: 19,  
    	    writable: true,  
    	    enumerable: true,  
    	    configurable: true  
    	},
    	// 定义一个访问器描述符  
    	look: {  
    	  get: function() {  
    	    return 'Hello, ' + this.name;  
    	  },  
    	  enumerable: true,  
    	  configurable: true  
    	} 
    })
    // 输出
    xiaoMing.name = "小明"
    xiaoMing.sex = "女"
    xiaoMing.say() // 小明说:我今年19了,我的性别是:女
    xiaoMing.look // 'Hello, 小明'
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3. 属性引用

    对象属性可以通过两种主要方式访问:点符号(.)和方括号([]

    // 1. 点符号(.)
    let obj = {  
      name: 'Alice',  
      age: 30,
      'my-prop': '自定义的属性' 
    };  
      
    console.log(obj.name); // 输出 'Alice'  
    console.log(obj.age);  // 输出 30
    
    // 2. 方括号([])
    console.log(obj['age']) // 输出30
    
    let propName = 'name';  
    console.log(obj[propName]); // 输出 'Alice'  
    
    console.log(obj['my-prop']) // 输出 自定义的属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二. 原型(prototype

    1. obj.prototype 对象的原型(每个函数对象才会拥有prototype
      prototype是函数对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承改原型的属性和方法,原型也是对象。
    2. __proto__
      • 每个对象都有__proto__属性,去访问自己的原型
      • 大多数对象最后的原型都会指向Object.prototype

      var obj = Object.create(null); // obj无原型,无__proto__,无constructor

      1. var obj = {};
        obj.__proto__ = Object.prototype;
      
      2. Person.prototype.name = '构造函数Person的原型'
        function Person(){};
        var person = new Person();
        person.name; // 访问先查看自身属性,没有去其原型上查找
        person.__proto__  ------>  Person.prototype
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    3. 每个原型对象都会自动获得一个constructor属性,这个属性指向创建它的构造函数。

      这样做的目的是为了在原型链上能够正确地追踪到实例的构造函数。
      通常,当你定义一个构造函数并创建它的实例时,这个实例的constructor属性会指向该构造函数。

      function Person(name, age) {  
        this.name = name;  
        this.age = age;  
      }  
        
      // 构造函数上prototype的constructor指向自己 
      console.log(Person.prototype.constructor === Person); // 输出: true  
      
      // 创建一个Person实例  
      let person = new Person('Alice', 30);  
        
      // 检查person的constructor属性  
      console.log(person.constructor === Person); // 输出: true  
      console.log(person.constructor.name); // 输出: "Person"
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    4. Object.create(proto, [propertiesObject]) 建一个新对象,使用现有的对象来提供新创建的对象的__proto__
    5. call, apply 改变this指向,

    callapply的主要区别在于它们如何接收参数:
    call接受一个参数列表,而apply接受一个参数数组。
    这两个方法都允许你改变函数内部的this上下文,这在处理回调函数、对象方法以及继承等场景中非常有用

    // 1. call
    function Car(age, sex){
      this.name = '小刘',
      this.age = age,
      this.sex = sex
    };
    var obj = {};
    Car.call(obj,112, '男'); // 将Car内this的指向指向 obj
    
      // 2. apply
    function Car(age, sex){
      this.name = '小刘',
      this.age = age,
      this.sex = sex
    };
    var obj = {};
    Car.apply(obj,[112, '女']);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    三. 继承、命名空间、对象枚举

    1. 继承

      // 继承方法
      var inherit = (function(){
        var F = function (){}; // 闭包私有化变量,不属于对象,和对象同属于同一个AO对象
        return function(Target,Origin){
          F.prototype = Origin.prototype;
          Target.prototype = new F();
          Target.prototype.constructor = Target;
          Target.prototype.uber = Origin.prototype;
        }
      }());
      
      function Car(name){
        this.name = name
      };
      Car.prototype.whool = 4;
      
      function BaoMa(){}
      
      inherit(BaoMa,Car);
      
      BaoMa.prototype.age = '百年历史';
      var baoma = new BaoMa();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    2. 命名空间

      // 1.
      var obj = {
          eat:{
            li:{
              name: '小李定义的eat'
            },
            zhang:{
              name: '小张定义的eat'
            }
          },
          drink:{
            li:{
                name:'小李定义的drink'
            }
          },
        };
        <!-- 调用 -->
        var li = obj.eat.li;
        li.name
      
      // 2. 利用闭包实现,不污染全局变量
      
      var name = '全局name变量';
      var init = (function (){
        var name = '函数内部name变量';
        function say(){
            console.log(name);
        }
        return function(){
           say()
        }
      }());
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
    3. 对象枚举

      1. for...in语句用于遍历一个对象的可枚举属性(包括自有属性和继承自原型链的属性)。它会枚举对象的每一个可枚举属性,并为每个属性执行一次循环体。
      var obj = {
        name:'小刘',
        age: 18,
        sex: 'male',
        wife: '小宋',
         __proto__:{
          lastName:'Deng'
        }
      }
      Object.prototype.abc = 123;
      for(var prop in obj){
      	console.log(`${prop} -- ${obj[prop]}`)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      1. hasOwnProperty是一个方法,用于检查一个对象自身(不包括其原型链)是否具有指定的属性
      // 上例 obj
      for(var prop in obj){
        if(obj.hasOwnProperty(prop)){
          console.log(`${prop} -- ${obj[prop]}`)
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      1. in 运算符用于检查对象自身及其原型链中是否存在某个属性。它会返回一个布尔值,如果对象或其原型链上有一个名为给定字符串的属性,则返回 true;否则返回false
      // 上例 obj
      console.log('name' in obj) // true
      console.log('abc' in obj) // true
      
      • 1
      • 2
      • 3
      1. instanceof是一个运算符,用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。换句话说,它用来判断一个对象是否是一个构造函数的实例
      // 区分数组[]和对象{}
      //  typeof([]); ---> object 
      //  typeof({}); ---> object
      var arr = [];
      var obj = {};
      // 1. instanceof 方法
      arr instanceof Array;  // true
      obj instanceof Array;  // false
      arr instanceof Object;  // true
      obj instanceof Object;  // true
      // 2. constructor 
      arr.constructor // function Array
      obj.constructor // function Object
      // 3. call toString
      Object.prototype.toString.call([]); // '[object Array]'
      Object.prototype.toString.call({}); // '[object Object]'
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    四、 this

    1. 函数预编译过程 this 指向window
    2. 全局作用域里 this指向window
    3. call/apply: 改变函数运行时 this指向
    4. obj.func()func()里的this 指向obj(谁调用指向谁)

    五、arguments 函数实参的类数组对象(use strict严格模式下禁用)

    1. arguments.length 对象长度
    2. arguments.callee 指向函数自身引用
    3. func.caller 函数的属性,函数被谁调用,返回谁
    // 'use strict' // 严格模式下禁用
    var num = (function (n) {
      if (n === 1) {
        return 1
      }
      return n * arguments.callee(n - 1)
    }(5))
    num // 120
    
    function demo() {
      test();
    }
    function test() {
      console.log(test.caller);
    }
    demo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    CleanMyMac X4.12.1苹果电脑系统优化软件更新功能介绍
    华为云CodeArts产品体验的心得体会及想法
    python:遗传算法(Genetic Algorithm,GA)求解23个测试函数
    四舍五入(c++基础)
    HIVE内置函数hash() -- 源码解析
    前端食堂技术周刊第 103 期:10 月登陆 Web 平台的新功能、TS 5.3 RC、React 2023 状态、高并发的哲学原理、Web 资源加载优先级
    。。。。。。。。。
    视野修炼-技术周刊第56期
    Hadoop总结——Hadoop基础
    Mysql高级——索引优化和查询优化(2)
  • 原文地址:https://blog.csdn.net/qq_35940731/article/details/138182830