对象封装:隐藏方法的具体实现,使用者直接调用即可。
封装方式:原生对象 、 工厂模式 、构造函数模式 、 原型模式 、 构造+原型
工厂模式
优点:创建简单
缺点:创建的对象之间没有任何联系
function createPerson(name,age,sex){ return { name: name , age: age, sex: sex, sing: function { console.log('开始唱歌'); } };}var person = createPerson('图图',6, 'unkown' )
构造函数模式
构造函数就是普通函数,内部通过$ extcolor{red}{this}$进行变量定义,通过$ extcolor{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');
原型模式
$ extcolor{red}{prototype}$ 构造函数上面,执行原型
普通对象,构造函数上面存在一片共有空间,所有当前的构造函数创建的对象都可以使用此空间。
$ extcolor{red}{proto}$ 实例对象(属性),指向构造函数的原型,私有属性
$ extcolor{red}{Object.getprototypeOf(obj)}$
$ extcolor{red}{constructor}$ 原型对象上,指向构造函数
$ extcolor{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
$ extcolor{red}{原型继承}$
父类的属性不会被创建在子类的原型内部
子类的原型以父类的原型所创建的对象
Cat.prototype = Object.create(Ani.prototype);//Object.create模拟function create(prototype){ function Fn(){} Fn.prototype = prtotype; return new Fn();}
$ extcolor{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);$ extcolor{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 对象中的数据,尤其有用。
java基础面试题继承封装
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/26501.html