js基础复习笔记关于对象

224 阅读6分钟

![](https://user-gold-cdn.xitu.io/2020/7/1/173094752b30ac7c?w=931&h=613&f=png&s=77913)

![](https://user-gold-cdn.xitu.io/2020/7/1/1730947acd0ff06a?w=742&h=357&f=png&s=31509)

![](https://user-gold-cdn.xitu.io/2020/7/1/1730947c60313fa9?w=960&h=689&f=png&s=69227)

![](https://user-gold-cdn.xitu.io/2020/7/1/1730947e46d43579?w=754&h=618&f=png&s=52389)
 /*
   1.编程语言常见的有两种,一种是基于类 一种是基于原型,基于类的代表java,原型的代表js
          1.1.基于类 总是先划分类关注类直接关系,要现有类再去创建一个对象
          1.2.基于原型,不会去显示定义一个类,而是会通过其他类实例添加属性和方法。也可以使用空对象直接创建
          
          区别: 基于原型是在不定义class 的情况下依然能创建一个object,
          
          相同:无论你是js 也好java也好本质都是面向对象,只是实现方式不同

          学习的时候一直对js产生疑问:在学习其他语言后,在学习js很多人都有迷茫,这个迷茫的原因,
          主要是历史原因,设计的时候模仿java导致引入了 'new ,this'一类的语言特性,让人忘记了
          他是基于原型,他有他的优势,以至于总是去用基于类的角度去看

          注:做一个心得,在java这类语言通过类创建好的对象,是不能再给对象添加属性和方法,相反js这类
          基于原型的语言就可以做到,做个不恰当的比喻,java写一个老虎你给规定这个老虎是东北虎 继承猫科类
          ,js就是这个老虎跟猫很像就是叫的声音大小不一样,我随意把猫这个对象加点东西减点东西就变成了老虎。
         可以理解成js更多的韵味在照猫画虎,站在两者本身设计上就是两种模式来理解,各有各的好处仅此而已

        2.首先js 是原型创建对象的,使用原型到对象有两种方式
          2.1. 第一种就复制一个对象,从此两个对象没有关系
          2.2. 不是真的复制原型对象,只是使得对象 持有一个原型的引用

        3.什么是对象  
           3.1.对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。
           3.2.对象有状态:对象具有状态,同一对象可能处于不同状态之下。
           3.3.对象具有行为:即对象的状态,可能因为它的行为产生变迁。
           注:大白话两个写法一样的对象不一定相等内存指向不同,行为状态就是属性和方法,js更喜欢把他们都叫属性
        
        4.es6开始js的类写法和java这类很像,但是js一等公民就是function,class只是一个语法糖,而且
        js 属性不是你单单看到的,一个属性使用一组特征来描述的属性 这就是' 数据属性/访问器属性'。
          4.1.数据属性决定了js定义中对象属性的'值','能否被赋值','被枚举','能否被删除就是delete'
          4.2.访问器属性 '读取属性时调用的函数','写入属性时调用的函数','被枚举','能否被删除就是delete'
    原型模式
    
    
    1.原型编程思想中,类并不是必须,对象也不是必须从类中创建
        1.1.一个是并不真的去复制一个原型对象,而是使得新对象持有一个原型的引用;
        1.2.另一个是切实地复制对象,从此两个对象再无关联。

    2.js 没有类的概念,所谓的类的概念只是写法上和具有类的语言相似,
    用mdn的话来说js是动态的并且本身也不提供class的实现

    3.站在原型的角度来说如果A对象是从B对象克隆来的,那么B对象就是A对象的原型,js
    中对象的原型都来自Object,但是js原型末端是null

    4.js的继承是通过原型链实现的
        4.1.所有数据都是对象,除了undefined
        4.2.要得到一个对象不是通过实例化实现的,而是找到一个对象作为原型并且克隆
        4.3.对象会记住他的原型 
        4.4.如果对象无法响应某个请求,他会把这个请求委托给自己原型
  */
    function DoSomething(){}
    console.log( DoSomething.prototype );
    DoSomething.prototype.name = 'wang'
    // {
    //     name: "wang",  ------------> name 属性是DoSomething自己的所以不是从他的copy原型来的,因此不再__proto__
    //     constructor: ƒ DoSomething(),
    //     __proto__: {    -----------------> 这里的原型链指向的是Object,这证明最开始说的'Object'就是所有对象的原型'
    //         constructor: ƒ Object(),
    //         hasOwnProperty: ƒ hasOwnProperty(),
    //         isPrototypeOf: ƒ isPrototypeOf(),
    //         propertyIsEnumerable: ƒ propertyIsEnumerable(),
    //         toLocaleString: ƒ toLocaleString(),
    //         toString: ƒ toString(),
    //         valueOf: ƒ valueOf()
    //     }
    // }

    const doSomething = new DoSomething()
    doSomething.age = 17
    console.log( doSomething) 
    // {
    //     age: 17, ---------》 age 属性是doSomething 的因此不再__proto__
    //     __proto__: { ---------》doSomething 是从DoSomething克隆来的因此一层原型链指向是DoSomething
    //         name: "wang",
    //         constructor: ƒ DoSomething(),
    //         __proto__: { -----------------》DoSomething 是从Object 来的因此第二层是在Object
    //             constructor: ƒ Object(),
    //             hasOwnProperty: ƒ hasOwnProperty(),
    //             isPrototypeOf: ƒ isPrototypeOf(),
    //             propertyIsEnumerable: ƒ propertyIsEnumerable(),
    //             toLocaleString: ƒ toLocaleString(),
    //             toString: ƒ toString(),
    //             valueOf: ƒ valueOf()
    //         }
    //     }
    // }
  /* -----------------------理解4.2---------------------------
    1.当js时候我们通过new 去生成对象,在java这里语言中new 就是一个实例化的过程,
    但js 是基于原型只是写法类似,但实际做的却大相近庭
    2.所以要做的不是实例化而是找到一个对象作为原型来克隆它
  */
    
    function Person( name ){
        this.name = name;
    };

    Person.prototype.getName = function(){
        return this.name;
    };

    var objectFactory = function(){
        // 创建一个 空对象
        var obj = new Object();
        // 获取构造函数
        var  Constructor = [].shift.call( arguments )
        // 改变当前obj 空对象原型链的指向
        obj.__proto__ = Constructor.prototype
        // 改变构造函数指向
        var ret = Constructor.apply( obj, arguments );    
        return typeof ret === 'object' ? ret : obj;     // 确保构造器总是会返回一个对象
    }

    // 这个写法等同  console.log(new Person('wang'))
    var a = objectFactory( Person, 'sven' ); 
    console.log(a)
    console.log( a.name );    // 输出:sven
    console.log( a.getName() );     // 输出:sven
    console.log( Object.getPrototypeOf( a ) === Person.prototype );