美文网首页
2018-11-23 面向对象4 ES6

2018-11-23 面向对象4 ES6

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

面向对象补充:

JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。
通过构造函数为实例对象定义属性,虽然很方便,但是有一个缺点。同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。
JavaScript 继承机制的设计思想就是,原型对象的所有属性和方法,都能被实例对象共享。也就是说,如果属性和方法定义在原型上,那么所有实例对象就能共享,不仅节省了内存,还体现了实例对象之间的联系。
JavaScript 规定,每个函数都有一个prototype属性,指向一个对象。这个对象就是函数的原型。

  • eg:1继承
    效果如下:


    25.1继承.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
let p = new F('小明','很胖');
function F(name ,skill){
    this.name = name;
    this.skill = skill;
}
F.prototype.shou = 2;
F.prototype.showName = function(){
    //字符串模板  ''  ""  `${}`
    return `我的名字叫做:${this.name}`;
}
F.prototype.showSkill = function (){
    return `我的技能是:${this.skill}`;
}
console.log(p.showName());
console.log(p.showSkill());

function Stu(name,skill,use){
    F.apply(this,[name,skill]);
    this.use = use ;
}
console.log(Stu.prototype.constructor);
Stu.prototype = new F('','');
console.log(Stu.prototype.constructor);
Stu.prototype.constructor = Stu;
console.log(Stu.prototype.constructor);
let liming = new Stu('李明','包揽了整个高中英语','use  less');
console.log(liming.showName());
console.log(liming.showSkill());

</script>
</body>
</html>
原型链:

JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……

如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性。也就是说,所有对象都继承了(多继承)

  • eg:2多继承
    效果如下:


    25.2多继承.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
function F(name,skill){
    this.name = name;
    this.skill = skill;
}

F.prototype.shou = 2;
F.prototype.showName = function(){
    //字符串模板''\""\`${}`
    return `我的名字叫做:${this.name}`;
}
F.prototype.showSkill = function(){
    return `我的技能是:${this.skill}`;
}
function M(sex){
    this.sex = sex;
}
M.prototype.showSex = function(){
    return `我的性别是:${this.sex}`;
}
function W(use){
    this.use = use;
}
W.prototype.showUse = function(){
    return`我的功能是:${this.use}`;
}
function Stu(name,skill,sex,use){
    F.apply(this,[name,skill]);
    M.call(this,sex);
    this.use = use;
}

Stu.prototype = Object.create(F.prototype);
Object.assign(Stu.prototype,M.prototype);
Object.assign(Stu.prototype,W.prototype);
Stu.prototype.constructor = Stu;
let z = new Stu('李华','高中英语','男','包揽了整个高中英语');
console.log(z.showName());
console.log(z.showSkill());
console.log(z.showSex());
console.log(z.showUse());
</script>
</body>
</html>
  • eg:3函数实现多继承
    效果如下:


    25.3函数实现多继承.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
function F(name,skill){
    this.name = name;
    this.skill= skill;
}
F.prototype.shou=2;
F.prototype.showName = function(){
    //字符串模板''\""\`${}`
    return `我的名字叫做:${this.name}`;
}
F.prototype.showSkill = function (){
    return `我的技能是:${this.skill}`;
}

function M(sex){
    this.sex = sex;
}
M.prototype.showSex = function(){
    return `我的性别是:${this.sex}`;
}

function Stu(name,skill,sex,use){
    this.use= use;
}
Stu.prototype.extends = function(obj,...man){
    obj.apply(this,[...man]);   //结构数组
    Object.assign(Stu.prototype,obj.prototype);
    Stu.prototype.constructor=Stu;
}

let z =new Stu('包揽了整个高中英语');
z.extends(F,'李明','高中英语');
z.extends(M,'男');

console.log(z.showName());
console.log(z.showSex());
console.log(z.showSkill());
</script>
</body>
</html>
  • eg:4.对象扩展
    效果如下:


    25.4扩展.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    function f(...m){
        console.log([...m]);    //扩展运算符(...)
    }
    f(1,222,333);
    </script>
</body>
</html>

Object.prototype的属性。这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的。

那么,Object.prototype对象有没有它的原型呢?回答是Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是null。

  • eg:5单方面的继承
    效果如下:


    25.5单方面的继承.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        function F(){

        }
        F.prototype.h= function(){
            console.log('h');
        }
        F.prototype.m=function(){
            console.log('m');
        }

        function L(){

        }
        L.prototype.m =function(){
            F.prototype.m.call(this);
        }

        let l = new L();
        l.m();
    </script>
</body>
</html>

constructor:
prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。

ES6

1、ES6面向对象:

class ----- 构造函数
对象 ----- 实例对象

  • eg:6ES6对象简写
    效果如下:


    25.6ES6对象简写.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    let name = '小明';
    let skill = '高中英语';
    let s = Symbol('s');    //对一无二的值
    let ss = Symbol('ss');
    console.log(s);
    console.log(ss);
    const obj ={
        name,
        skill,
        say(){
            console.log('say');
        },
        [s]:s,
    };

    console.log(obj.name)
    obj.say();
    console.log(obj[s])
    </script>
</body>
</html>
  • eg:7面向对象
    效果如下:


    25.7ES6面向对象.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        const a = Symbol(); //常量
        class Person{
            constructor(name,skill){    //构造函数,new的时候自动的调用的,用于初始化的。自动传递参数
                this.name = name;
                this.skill=skill;
            }   //在此处有constructor所以不能有逗号
            showName(){
                console.log(`我的名字:${this.name}`);
            }
            showSkill(){
                console.log(`我的技能:就是${this.skill}`);
            }
            [a](){
                console.log(`我是Symbol数据类型的函数名`);
            }
        }
        console.log(typeof Person);
        let p1 =new Person('李明','高中英语');
        p1.showName();
        p1.showSkill();
        p1[a]();
    </script>
</body>
</html>
  • ES5面向对象是模拟面向对象。
    实例:
    人类 张三
    动物类 熊猫
    鸟类 黄鹂
    植物类 仙人球
    哺乳动物 人

(1)、constructor: 类的构造函数,类在实例化的时候自动调用。参数自动传递。
(2)、class 的属性名可以是变量,但是这个变量需要使用[]包装起来,表示变量的解析。
class的内在本质还是一个function。

  • eg:9class结构
    效果如下:


    25.9class结构.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        class P{
            constructor(name){
            this.name=name;
            }
            say(){
                console.log(this)
                console.log(this.name);
            };
        }
        let p1 =new P('李明');
        p1.say();

        let {say}=p1;

        say.bind(p1);
    </script>
</body>
</html>

对于ES5的构造函数来说,本质上定义的是一个函数,函数和变量一样,具有提升的特性,所以可以在构造函数的申明之前进行实例化。 class没有提升,所以在创建类对象的时候一定要保证类是先加载的。

  • eg:8class没有提升
    效果如下:


    25.8class没有提升.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    let pp= new P();
    class P{
        constructor(){//constructor构造函数是class必须的,即使没有声明 ,那么class也会自动的添加一个空的constrcutor函数。
        }
    }
    </script>
</body>
</html>
2、setter与getter:

封装class内部成员属性的作用。
语法。
自动能调用。
(1)、set 语法定义的函数,外部在调用函数名为属性的属性设置值的时候调用。
(2)、get 语法定义的函数。外部在获取这个函数名为属性的属性的时候调用。

  • eg:10get 与 set
    效果如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        class P{

        }
        const Person = class{
            constructor(name){
                this.name= name;
            }
            /*
            set age(value){
                设置这个值的时候会自动调用console.log('这里调用参数的设置');
                let c = value ;
                console.log(c);

            } */
            get age(){
                console.log('这里调用了参数的获取')
                return 111111111;
            }
        }

        let p1 =new Person('李明');
        console.log(p1.name)
        p1.name = '高中英语';       //公共属性

        console.log(p1.age)
        p1.age =22222222222222222;
        console.log(p1.age)
    </script>
</body>
</html>

有的时候我们需要不创建你对象,直接使用类去执行某些事情,这个时候就可以设计静态方法。
(3)、static 静态的。不需要实例化对象去调用的方法。
静态方法里面的this指类本身。而不是对象。
静态方法直接使用类名调用,不能使用对象调用。
静态的类: Math
实例:
var proxy = new Proxy(target, handler);
target : 要进行代理的对象。
handler:代理的规则。
代理:帮助做一些事情。

  • eg:11 static
    效果如下:


    25.11static.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
class P {
    constructor(){}
    say(){
        console.log(this);  //实例对象
        console.log('1111111111111');
    }
    static ss(){
        console.log(this);  //class
        console.log('2222222222222222222');
    }
}
let p = new P();
p.say();

P.ss();
</script>
</body>
</html>

(4)extends继承

  • eg:12extends
    效果如下:


    25.12extends.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    class F{
        constructer(name){
            this.name = name;
        }
        say(){
            console.log(this.name);
        }
        static s(){
            console.log('ssssssssssssssssssss');
        }
    }
    class W extends F{
        constructor(name,age,skill){
            //如果没有设置constructor,那么这个构造函数就是继承自父类。
            //但是一旦自己设置了constructor函数,规定在内部必须调用父亲的构造函数
            super(name);    //表示调用父类的构造函数

            this.age = age ;
            this.skill = skill;
            this.name = name;
        }
        eat(){
            console.log('eat');
        }
        say(){      //重写 overriding
            super.say();    //super表示父级
            console.log('33333333333333');
        }
    }

    let t = new W('lalalalalalala');
    t.say();
    t.eat();

    W.s();      //继承静态的方法
    </script>
</body>
</html>

(5)、proxy
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

  • eg:13proxy
    效果如下:


    25.13proxy.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
const obj = {//const
    a:12,
    b:'abc',
    c:1111111,
    d:'liming'
};
const c = new Proxy(obj,{
    get: function(a,b,c){
        //console.log(a);//第一个参数是代理对象
        //console.log(b);  //代理的属性
        //console.log(typeof  a[b])
        //console.log(a[b].prototype)

        if(typeof a[b] =='number'){
            return a[b];
        }
        return 2;
    }
});

console.log(c.d);
</script>
</body>
</html>

(6)、reflect
*Reflect*对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。*Reflect*对象的设计目的有这样几个。
Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在ObjectReflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

效果如下:


25.reflect.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
const obj = {
    a:122222,
    b:'liming'
};

let c = new Proxy (obj,{
    set:function(target,name,value,receiver){
        var success = Reflect.set(target,name,2,receiver);
        console.log(success);
        if(success){

        }
        return success;
    }
});
c.a = 1111111;
console.log(c.a);
</script>
</body>
</html>

相关文章

  • 2018-11-23 面向对象4 ES6

    面向对象补充: JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法...

  • ES6面向对象

    1、ES6面向对象: class(类) 构造函数 对象 实例对象 ES5面向对象是模拟面向对象。 2、继...

  • ES6的面向对象

    ES6面向对象 [TOC] 继承:

  • JavaScript之面向对象编程

    五、面向对象编程 目录:面向对象原型继承、面向对象class继承(ES6引入的) 1.面向对象原型继承 类:模板 ...

  • JavaScript 面向对象编程

    写法 ES6面向对象的写法---类继承

  • JavaScript OOP篇

    参考资料 JavaScript面向对象简介 ES6对象的拓展 ES6 class 前言 本篇主要介绍 JavaSc...

  • 面向对象的小九九

    面向对象 本人能力有限,有误请斧正 本文旨在复习面向对象(不包含es6) 本文学习思维 创建对象的方式,获取对象属...

  • ES6之面向对象

    关键词:面向对象 es6新增了类这个语法糖

  • 面向对象 类

    一、回顾面向对象new函数构造:new生成一个对象,new必须加上。构造出来的内容必须大写 es6的面向对象,cl...

  • 第八周第五天笔记之es6+面向对象+jQuery版左右切换轮播图

    1 es6+面向对象+jQuery版左右切换轮播图实例 思路:es6中面向对象的创建,用class创建类全局属性放...

网友评论

      本文标题:2018-11-23 面向对象4 ES6

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