Java封装、继承、解析解构

136 阅读4分钟

封装、继承、解析解构

对象封装:隐藏方法的具体实现,使用者直接调用即可。

封装方式:原生对象 、 工厂模式 、构造函数模式 、 原型模式 、 构造+原型

工厂模式

优点:创建简单

缺点:创建的对象之间没有任何联系

function createPerson(name,age,sex){

return {

name: name ,

age: age,

sex: sex,

sing: function {

console.log('开始唱歌');

}

};

}

var person = createPerson('图图',6, 'unkown' )

构造函数模式

构造函数就是普通函数,内部通过textcolorredthis\\textcolor{red}{this}进行变量定义,通过textcolorrednew\\textcolor{red}{new}关键字生成对象

*如果不使用new 关键字调用构造函数,构造函数内部的参数会污染全局变量

构造函数首字母需大写

优点:通过构造函数创建的对象可以进行判断

缺点:所有属性和方法都会被重复创建,浪费资源

function Person(name,age,sex) {

this.name = name;

this.age = age;

this.sex = sex;

this.sing = function (){

console.log('开始唱歌");

};

}

var person5 = new Person('图图',6,'unkown');

var person6 = new Person('图图',15,'unkown');

原型模式

textcolorredprototype\\textcolor{red}{prototype} 构造函数上面,执行原型

普通对象,构造函数上面存在一片共有空间,所有当前的构造函数创建的对象都可以使用此空间。

textcolorredproto\\textcolor{red}{proto} 实例对象(属性),指向构造函数的原型,私有属性

textcolorredObject.getprototypeOf(obj)\\textcolor{red}{Object.getprototypeOf(obj)}

textcolorredconstructor\\textcolor{red}{constructor} 原型对象上,指向构造函数

textcolorred原型链\\textcolor{red}{原型链}

function Foo(){}

function Foo1(){}

Foo1.prototype = new Foo();

var f3 = new Foo1();

console.log(f3.__proto__);

//返回f3构造函数的原型 Foo

console.log(f3.__proto__.__proto__);

//返回f3构造函数的原型Foo 的构造函数的原型Object

Foo.prototypeconsole.log(f3.__proto__.__proto__._proto__);

//null

原型 + 构造

结合两者的特点,将需要变化的属性写入构造函数,将不变的写入构造函数的原型

继承

主要使用原型链进行实现

1.原型链 2. 构造函数 3.组合继承 4.寄生组合继承 5.class(ES6是寄生组合继承的语法糖)

· 原型链继承

缺点:

1. 只继承父类的原型,不能使用父类的构造函数

2. 父类的属性会被创建在子类的原型内部

3. 子类的原型为父类的实列对象

function Ani(name){

this.name = name;

}

Ani.prototype.sayHello = function (){

console.log('你好,柯基');

}

var ani = new Ani('狗子');

console.log(ani);

function Cat(name){

this.name = name;

}

Cat.prototype = new Ani();

Cat.prototype.constructor = Cat;

var cat = new Cat('喵');

console.log(cat)

//cat - Cat.prototype → Ani.prototype → 0bject.prototype → null

textcolorred原型继承\\textcolor{red}{原型继承}

父类的属性不会被创建在子类的原型内部

子类的原型以父类的原型所创建的对象

Cat.prototype = Object.create(Ani.prototype);

//Object.create模拟

function create(prototype){

function Fn(){}

Fn.prototype = prtotype;

return new Fn();

}

textcolorred构造函数\\textcolor{red}{构造函数}(借用构造函数)

缺点:只能使用父类的构造函数,无法获取父类的原型相关内容

function Ani( name,age) {

this.name = name;

this.age = age;

}

Ani.prototype.sayHello = function () {

console.log('你好,我是狗");

};

var ani1 =new Ani('狗子',2);

function Cat( name, age, type) {

Ani.call( this,name,age);

this.type = type ;

}

var cat =new Cat(‘瞄‘,1,"英短");

console.log(cat);

更改this指向

call

使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数

var obj = {a: 1};

var ani2 = Ani.call(obj,'豆包包',2);

console.log(obj);

apply

调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

var obj = {a: 1};

var ani3 = Ani.apply(obj,['豆包包',2]);

console.log(obj)

bind

用于绑定对应函数的this指向和传入的数据,并返回新函数

var obj = {a: 1};

var ani4 = Ani.bind(obj,'豆包包',2);

console.log(ani4());

var obj = {a: 1};

var ani4 = Ani.bind(obj,'豆包包');

console.log(ani4('豆包包3号'));

call运用(类数组转数组)

组合继承(原型+构造函数)

缺点:在实现继承时,父类被调用两次 ,耗费内存

function Ani( name,age) {this.name = name ;

this.age = age;}

Ani.prototype.say = function( {

console.log( 'hahhaa ' );

};

1/子类

function Cat(name,age,type) {

Ani.call(this,name,age); //构造继承this.type = type;

}

1/原型继承

Cat.prototype = new Ani();

Cat.prototype.constructor = Cat;

var cat = new Cat('瞄',1,'布偶');

console.log(cat);

textcolorred寄生组合继承\\textcolor{red}{寄生组合继承}(构造+原型)

解析解构

1、数组解构

如果解构不成功,值等于undefined

let [a, b, c] = [1, 2, 3];

let [head, ...tail] = [1, 2, 3, 4];

head // 1

tail // [2, 3, 4]

解构赋值允许指定默认值

let [x, y = 'b'] = ['a']; // x='a', y='b'

let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

对象解构

根据属性名进行一一匹配

解构不成功,值等于undefined

//1.一般解构

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };

foo // "aaa"

bar // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };

baz // undefined

//2.替换值

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };

baz // "aaa"

//3.默认值

var {x: y = 3} = {x: 5};

y // 5

2、函数参数解构赋值

function add([x, y]){

return x + y;

}

add([1, 2]); // 3

function move({x = 0, y = 0} = {}) {

return [x, y];

}

move({x: 3, y: 8}); // [3, 8]

move({x: 3}); // [3, 0]

move({}); // [0, 0]

move(); // [0, 0]

3、解构用途

交换变量

提取 JSON 数据

解构赋值对提取 JSON 对象中的数据,尤其有用。