美文网首页
面向对象2

面向对象2

作者: 聽說_0100 | 来源:发表于2018-11-22 20:33 被阅读0次

    JavaScript的面向对象是基于constructor(构造函数)与prototype(原型链)的。

    构造函数:constructor

    构造函数就是一个函数。和普通函数有一些区别。
    constructor: 构造器。指向自己的构造函数。
    区别:
         1.函数的内部使用this的关键字。
         2.首字母是大写的。
         3.使用的时候要用new操作符创建实例对象。
    

    原型:prototype

    原型是一个对象,称为原型对象。
    构造函数创建实例对象,构造函数具有原型
    实例对象也具有原型。实例对象的原型指向构造函数的原型。这就是原型链。
    __proto__:每一个实例对象都具有的私有属性。指向自己的原型。
    

    new 创建对象实例

    防止漏掉new造成错误:

    • 在构造函数内部使用严格模式。
    • 使用instanceof在内部判断。判断是否为当前对象的实例。
    • 使用new.target 在内部判断,new.target指向自己的构造函数。
      eg:
    <script type="text/javascript">
        //在构造函数内部使用严格模式
        function A(name){
            'use strict';
            this.name = name;
        }
        let a = new A('lisi');
        //使用instanceof在内部判断,判断是否为当前对象的实例
        function B(name){
            //this 指向新创建的实例
            if(!(this instanceof B)){
                return new B(name);
            }
            this.name = name;
        }
        let b = new B('lisi');
        console.log(b.name);
        let bb = B('sisi');
        console.log(bb.name);
        //使用new.target在内部判断,new.target指向自己的构造函数
        function V(name){
            if(!(new.target == V)){
                throw new Error('这个对象必须使用new来创建新对象')
            }
            this.name = name;
        }
        let v = new V('ll');
        let vv = v('ll');//当不使用new的时候就会报错
    </script>
    

    new的深入操作

    1.创建一个空对象,作为将要返回的对象实例。
    2.将这个空对象的原型,指向构造函数的prototype属性。 
    3.将这个空对象赋值给函数内部的this关键字。
    4.开始执行构造函数内部的代码。
    5.将对象实例返回
    

    构造函数里面的return语句

    1.如果return的是普通数据类型。那么相当于没写。
    2.如果返回的是this,那么返回的与本身返回的是一样的。
    3.如果返回的是一个其他对象。那么结果返回的就是这个对象。
    所以在构造函数内部返回对象要小心。
    

    eg:

    <script type="text/javascript">
        //如果return是普通数据类型,那么相当于没写
        function A(name){
            this.name = name;
            return 123;//简单数据类型
        }
        let a = new A('12');
        console.log(a);
    
        //如果返回的是this,那么返回的与本身返回的是一样的
        function B(name){
            this.name = name;
            return this;
        }
        let b = new B('12');
        console.log(b);
    
        //如果返回的是一个其他对象,那么结果返回的就是这个对象,所以在构造函数内部返回对象要小心
        function C(name){
            this.name = name;
            return {
                name:'liso'
            };
        }
        let c = new C('12');
        console.log(c);//object
    </script>
    

    任何一个函数都可以使用new。返回值都是一个对象。
    如果这个函数是一个构造函数的话,返回的是这个函数的实例。
    如果函数是一个普通函数,那么返回的是一个空的对象。

    eg:

    <script>
        console.log(Object.prototype.__proto__);
        //Object的原型指向null,一切对象的基础是null,null也叫空。
        //Object对象是所有JS对象的基础
    </script>
    

    Object.create();

    有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。
    对于对象来说,每一个属性 其实都有四个描述。
    value 值
    enumerable 枚举 遍历 for in
    configurable 修改
    writable 删除
    后面三个默认值都是true。
    eg:

    <script>
        function A(name){
            this.name = name;
        }
        let a = new A('lisi');
        let b = Object.create(a);
        //有时候我们拿不到对象的构造函数,可以根据这个对象(Object.create())的某一个实例去创建一个对象
        console.log(b);
        b.name = 'zhangsan';
        console.log(a.name);
    </script>
    
    <script type="text/javascript">
        let obj = new Object();
        //添加属性
        obj.p1 = 'zhangsan';
        obj.p2 = 18;
    
        let obj2 = Object.create(obj,{//修改属性的值
            //对于对象来说每一个属性其实都有四个描述
            //value(值)、enumerable(枚举 遍历)、configurable(修改)、writable(删除)后面三个描述默认值为true
            p1:{
                value:'lisi',
                enumerable:false,
            },
            p2:{
                value:19,
                enumerable:true,
                configurable:true,
                writable:true,
            }
        });
        console.log(obj2);
        //遍历
        for(let i in obj2){
            console.log(i,obj2[i]);
        }
    </script>
    
    <script type="text/javascript">
        var obj = {
            a:'a',
            b:'b',
            c:'c',
        };
        for(let i in obj){
            console.log(i,obj[i]);
        }
        console.log('------------');
        //当enumerable的值为false时它对应的值就不会显示了
        Object.defineProperty(obj,'c',{
        //Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
            value:13,
            enumerable:false,
        });
        for(let i in obj){
            console.log(i,obj[i]);
        }
    </script>
    

    Object.getPrototypeOf(obj)

    <script type="text/javascript">
        function A(name){
            this.name = name;
        }
        let a = new A('zhangsan');
        console.log(Object.getPrototypeOf(a));//获取实例对象的原型
        console.log(a.__proto__);
    
        Object.getPrototypeOf({}) === Object.prototype;//ture
        //new Object 与 Object 的原型是一致的,对象的原型与构造函数是一致的。
    
        Object.getPrototypeOf(Object.prototype) === null
        //Object对象的原型的原型指向null,null也是原型链的顶点
    
        function f(){
            Object.getPrototypeOf(f) === Function.prototype //true
            //构造函数的原型与内置对想function的原型相同 f === new Function();
        }
    </script>
    

    Object.setPrototypeOf(obj)

    <script type="text/javascript">
            let a = new Array();
            console.log(Object.getPrototypeOf(a));
            Object.setPrototypeOf(a,Number.prototype);
            //setPrototypeOf()设置一个指定对象的原型到另外一个对象或null;
            console.log(Object.getPrototypeOf(a));
    </script>
    

    isPrototypeOf()

    <script type="text/javascript">
        let a = new Array();
        let b = new Array();
        console.log(Array.prototype.isPrototypeOf(b));//true
    
        let c = Array.prototype;
        console.log(c.isPrototypeOf(b));//true
        //判断该对象是否为参数对象的原型
    </script>
    

    Object.prototype.hasOwnProperty()

    Object.getOwnPropertyNames()

    <script type="text/javascript">
        function A(name){
            this.name = name;
            this.say = function(){
                console.log(a);
            }
        }
        A.prototype.ss = function(){
            console.log('ss');
        }
    
        function B(name){
            A.call(this);//继承
            this.age = 16,
            this.sex = 'man'
        };
        for(let i in A.prototype){
            B.prototype[i] = A.prototype[i];
        }
        console.log(Object.prototype);
    
        let b = new B('lala');
        b.ss();
        console.log(Object.getOwnPropertyNames(b));
        //getOwnPropertyNames成员是参数对象本身的所有属性的键名,不包含继承的属性键名
        console.log(B.prototype.hasOwnProperty('say'));//false
        //prototype.hasOwnProperty用于判断某个属性定义在对象本身还是定义在原型链上
    

    相关文章

      网友评论

          本文标题:面向对象2

          本文链接:https://www.haomeiwen.com/subject/rddrqqtx.html