美文网首页
2018-11-22 面向对象3

2018-11-22 面向对象3

作者: 满天繁星_28c5 | 来源:发表于2018-11-22 20:04 被阅读0次

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

    1.构造函数:constructor

    构造函数就是一个函数。和普通函数有一些区别:

    • 函数的内部使用this的关键字。
    • 首字母是大写的。
    • 使用的时候要用new操作符创建实例对象。
    2.原型:prototype

    原型是一个对象,称为原型对象。
    构造函数创建实例对象,构造函数具有原型,实例对象也具有原型。实例对象的原型指向构造函数的原型。这就是原型链。

    3.原型链:
    4.proto:每一个实例对象都具有的私有属性。指向自己的原型。

    proto属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括 IE11)都部署了这个属性。
    eg:1__protp___
    效果如下:

    22.proto.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    let a = new Array();
    console.log(a);
    
    function A(){
        this.a = '1';
    }
    let b = new A();
    console.log(b.__proto__)
    console.log(A)
    </script>
    </html>
    

    constructor: 构造器。指向自己的构造函数。

    5.new :

    创建对象实例。
    防止漏掉new造成错误:
    在构造函数内部使用严格模式。
    使用instanceof在内部判断。判断是否为当前对象的实例。
    使用new.target 在内部判断,new.target指向自己的构造函数。
    eg:2new
    效果如下:


    22.new1.jpg 22.new1.1.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    ll = 'lala';
    function A(name){
        console.log(this);      //此处的this指代的是全局作用域window
        this.ll = name;
        function ss(){
            alert(this.ll);
        }
    }
    A.prototype.say  = function(){
        alert(this.ll);
    }
    /*
    let a = new A ('zhangsan');
    a.say();    //页面弹出“zhangsan”的字样打印A{}的数组
    */
    let a = A('lili');
    console.log(ll)     //页面打印window的全局作用域 、 lili
    </script>
    </html>
    

    eg:3new
    效果如下:


    22.new2.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    function A (name){
        'use strict';  //严格模式
        this.name = name;
    }
    
    let a = new A('lisi');
    
    //递归
    function  B(name){
        // this指向新创建的实例
        if(!(this instanceof B)){
            return new B(name);
        }
        this.name = name;
    }
    let b = new B('lili');
    console.log(b.name);
    let bb = B ('sisi');
    console.log(bb.name);
    
    //new.target指向自己的构造函数
    function V (name){
        if(!(new.target == V)){
            throw new Error('这个对象必须使用new来创建对象');
        }
        this.name = name;
    }
    let v  = new V('kk');
    let vv = V('kk');
    </script>
    </html>
    
    6.new的深入操作:

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


    22.new3.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    function A(name){
        this.name = name;
        return  123;    //简单数据类型
    }
    let a = new A('123');
    console.log(a);     //打印出的是A数组里面的内容
    
    function B(name){
        this.name = name;
        return this;
    }
    let b = new B('123645');
    console.log(b);     //打印出的是B数组里面的内容
    
    
    function C(name){
            this.name = name;
            return {
                name:'zhangsan'
            };
    }
    let c = new C('1689156');
    console.log(c);    //打印出的是C数组里面的内容
    </script>
    </html>
    
    7.构造函数里面的return语句:

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

    8.任何一个函数都可以使用new。返回值都是一个对象。

    如果这个函数是一个构造函数的话,返回的是这个函数的实例。
    如果函数是一个普通函数,那么返回的是一个空的对象。

    9.Object对象,是所有JS对象的基础。

    Object 的原型指向null。一切对象的基础是null,null也叫空。
    eg: 5 Object
    效果如下:


    22.5Object.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    console.log(Object.prototype.__proto__);    //打印得null说明打印出的是对象原型是空
    </script>
    </html>
    
    9.(1)Object.create();

    有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。
    eg:6create
    效果如下:


    22.6create.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    function A(name){
        this.name = name;
    }
    let a = new A('LILI');
    
    let b = Object.create(a);       //有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。
    
    console.log(b);     //A name: "zhangsan"__proto__: A  此处获取的是b.name的命名'zhangsan'
    
    b.name = 'zhangsan';
    console.log(a.name);    //LILI 此处获取的是a中为A创建的一个实例'LILI'
    </script>
    </html>
    

    对于对象来说,每一个属性 其实都有四个描述。
    value 值
    enumerable 枚举 遍历 for in
    configurable 修改
    writable 删除
    后面三个默认值都是true。
    eg:7create
    效果如下:


    22.7create.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    let obj = new Object();
    //添加属性
    obj.p1 = 'lili';
    obj.p2 = 16;
    
    let obj2 = Object.create(obj,{  //有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。(后面三个默认值都是true。)
        /*value:值
        enumerable:true,
        configurable:true,
        writable:true
        */
    
        p1:{
            value:'llaaa',
            enumerable:false,       //*
        },
        p2:{
            value:56,
            enumerable:true,
            configurable:true,
            writable:true,
        }
    });
    for(let i in obj){  //让i拥有obj的值
        console.log(i,obj2[i]);     //打印出p1 llaaa, p2 56
    }
    </script>
    </html>
    

    eg:8.enumerable
    效果如下:


    22.8enumerable.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    var obj = {
        a:'a',
        b:'b',
        c:'c',
    };
    for(let i in obj){  //让i拥有obj的值
        console.log(i,obj[i]);
    }
    console.log('___________________________')
    Object.defineProperty(obj,'c',{
        value:13,
        //可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中。一般enumerable后面跟的值true
        enumerable:false,
    });
    for(let i in obj){
        console.log(i,obj[i]);
    }
    </script>
    </html>
    
    9.(2)Object.getPrototypeOf(obj)

    获取obj对象实例的原型
    eg:9Object.getPrototypeOf
    效果如下:


    22.9getprototypeof.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    function A(name){
        this.name = name;
    }
    let a = new A('lili');
    console.log(Object.getPrototypeOf(a));  //获取对象原型
    console.log(a.__proto__)
    Object.getPrototypeOf({}) === Object.prototype  //true
    //new Object 与Object的原型是一致的。对象的原型与构造函数的原型是一致的。
    
    Object.getPrototypeOf({})===null
    
    //Object对象的原型的原型指向null。null也是原型链的顶点。
    
    function f(){}
        Object.getPrototypeOf(f)===Function.prototype  //true
    //构造函数的原型与内置对象function的原型相同。f=== new Function();
    
    </script>
    </html>
    
    9.(3)Object.prototype.isPrototypeOf() 判断该对象是否为参数对象的原型

    eg:console.log(Array.prototype.isPrototypeOf(b));

    obj1.isPrototypeOf(obj2)
    判断obj2的原型是否是obj1。

    9.(4)Object.setPrototypeOf(obj)设置obj对象实例的原型

    eg:10setPrototypeOf
    效果如下:


    22.10Object.setPrototypeOf.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    let a = new Array();
    //Object.getPrototypeOf(obj)获取obj对象实例的原型
    console.log(Object.getPrototypeOf(a));
    //Object.setPrototypeOf(obj)设置obj对象实例的原型
    Object.setPrototypeOf(a,Number.prototype);
    
    console.log(Object.getPrototypeOf(a));
    </script>
    </html>
    
    9.(5)Object.getOwnPropertyNames() 成员是参数对象本身的所有属性的键名,不包含继承的属性键名。

    eg:12Object.getOwnPropertyNames()
    效果如下:


    22.12Object.getOwnPropertyNames().jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    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];
    }
    let b = new B ('lala');
    b.ss();
    //Object.getOwnPropertyNames()    成员是参数对象本身的所有属性的键名,不包含继承的属性键名。
    console.log(B.prototype.hasOwnProperty('say'));     //ss  false
    </script>
    </html>
    
    9.(6)Object.prototype.hasOwnProperty() 用于判断某个属性定义在对象自身,还是定义在原型链上。
    10.函数属性的区别:
    • 私有属性 : 在对象的定义中定义的非全局变量(在对象的定义中定义的非全局变量这种方式定义的属性,类的实例不能访问;只能通过 类名.属性名访问)
    • 实例属性 : 使用this为对象附加实例属性/对象名称.属性名(这种方式定义的属性,只能通过类的实例访问.不同实例之间共享该属性;不能通过 类名.属性名的方式访问)
    • 类属性 : "类"名.属性名/类名.prototype.属性名
      eg:13私有属性与实例属性
      效果如下:
      22.13私有属性.jpg
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    function F(name){
        A.call(this);   
        B.call(this);      //此处的A.call 与B.call是属于实例函数   这种方式定义的属性,只能通过类的实例访问.不同实例之间共享该属性;不能通过 类名.属性名的方式访问
        let ll = name ;   //私有成员  此处的‘ll’是私有属性私有属性  在对象的定义中定义的非全局变量这种方式定义的属性,类的实例不能访问;只能通过 类名.属性名访问
        this.getName = function(){
            console.log(ll);
        }
    }
    
    let f = new F('lili');
    
    f.getName();
    </script>
    </html>
    
    11.命名空间

    eg:14命名空间

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
    //适用于大型项目组
    
    
    //在所有的调用函数前设置一个qq的命名,让所有的要调用的函数都包含在qq中以避免与项目组的成员之间的项目函数调用重名
    var qq= {
        this.F = function(){
    
        }
        this.S = function(){
    
        }
    };
    
    li.F()
    </script>
    </html>
    

    相关文章

      网友评论

          本文标题:2018-11-22 面向对象3

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