009 Javascript(101 - 108)
[A] 解构
解构两大类:
中括号解构
大括号解构
1. 中括号解构可用于变量批量赋值
[x, y, z] = [23,56,78]; 按位置对应赋值
[x, [a, b], z] = [23,[45,43],78]; 按位置对应赋值
2. 大括号结构用于对象赋值
{name, age, sex, action} = { name: "jack", age: 18, sex: "男" action = function(){ alert("helow"); } }
3. 解构的好处:
a. 交换两个数变得更加方便
[a, b] = [b, a]; // 交换a, b两个数的值
b. 函数可以返回多个值
fucntion fun(形参){ return ["结果1", "结果2", "结果3"]; } 调用: [a, b, c] = fun(实参);
c. 调用函数时,实参不必和形参一一对应
【注】此时,参数可以自带默认值
function show({name, age = 18, sex}){ aler("我叫" + name + ", 今年" + age + "岁了,是一个" + sex + "性。"); } 调用:这里传入的大括号结构后的参数 show({ name: "jack", age: 18, sex: "男", })
d. 快速取出数组中的一个元素
var arr = [10, 20, 30, 40, 50]; var {0:first, 4:last} = arr; // 通过解构,将数组arr的下标为0的元素赋值给first // 将数组arr的下标为4的元素赋值给last alert(first);
[B] ECMA6字符串
1. 传统字符串:所有单引号和双引号括起来的都叫做字符串
2. ECMA6字符串:反引号`` 英文键盘下按下键1可打出来
3. ECMA6字符串优点:
a. 传统字符串书写时不能换行
而ECMA6字符串可以随便写,写出来什么样,输出出来就是什么样。
传统写法:var str = "hello
world" // 将报错
ECMA6写法:var str = `hello
world` // 可以正确输出
b. 通过占位符 ${} 实现字符串拼接
var name = "jack";
var age = 18;
var sex = "男";
传统写法:
str = "我叫" + name + ", 今年" + age + "岁了,是一个" + sex + "性。";
ECMA6写法:
str = `我叫${name},今年${age}岁了,是一个${sex}性`。
[C] 新增能数组方法和合并对象
ECMA6新增数组方法:
1. Array.from() 将伪数组转成真数组,即从一个类似数组或可迭代对象中创建一个新的数组实例。
2. find() 在数组中查找符合条件的元素,只要找到第一个符合条件的元素,就终止遍历
返回值:找到的元素
var arr = [10, 20, 30, 40, 50]; var re = arr.find(function(item, index, arr){ return item > 20; }); // 返回30 alert(re); 或者用箭头函数: var re = arr.find(item => item > 20);
3. findIndex() 用法类似于find
在数组中查找符合条件的元素,只要找到第一个符合条件的元素,就终止遍历
返回值:找到的元素下标
4. copywithin() 用于从数组的指定位置拷贝元素到数组的另一个指定位置中。
第一个参数:覆盖的起始位置
第二个参数和第三个参数:元素拷贝的范围
如:arr.copywithin(3, 6, 9):将arr数组的下标为6-9的元素拷贝病覆盖掉从下表3开始的元素
合并对象
将多个对象的属性和方法合并到第一个对象中去,其中数组为浅拷贝。
【语法】Object.assign(对象1,对象2,对象3,......)
浅拷贝:只拷贝对应变量的地址,此时数据的修改会相互影响。
深拷贝:将对应变量的数据重新生成一份再赋值给指定变量,此时两个数据各自的修改不会相互影响。
[D] 集合和英汉词典案例
练习
1. 集合的特点:
a. 不重复
b. 无序
2. Set集合
【特点】键和值是相同的
创建:
通过new关键字创建
var s = new Set(值);
添加元素
通过add方法添加
s.add(100);
遍历元素 for...of
1. 值遍历
var jh = new Set(); jh.add(100,200); jh.add("jihao"); jh.add([3,4,6]); for(let item of jh.keys()){ document.write(item,"<br>");
}
var jh = new Set(); jh.add(100,200); jh.add("jihao"); jh.add([3,4,6]); for(let item of jh.values()){ document.write(item,"<br>"); }
var jh = new Set(); jh.add(100,200); jh.add("jihao"); jh.add([3,4,6]); for(let item of jh.entries()){ document.write(item,"<br>"); }
【注】重复添加的相同元素只有一个有效,这里是指元素的地址相同时不重复添加
利用集合元素不重复的特性,可以通过将数组转换成set集合,再将set转换成数组便可去除数组中的重复元素
【实现方法】
var arr = [10, 20, 50, 20, 30, 30]; 1. 数组变集合 var newSet = new Set(arr); 2. 集合变数组 var newArr = [...newSet];
3. map集合:
【特点】键和值可以不同
1. 创建:
通过new关键字创建
var m = new Map();
2. 添加元素
通过set方法添加
m.set(键,值);
3. 遍历元素 for...of
通过解构的方法遍历
var m = new Map(); m.set("张三", "打鱼的"); m.set("李四", "打柴的"); m.set("王五", "打滚的"); m.set("赵六", "打树的"); for(let [key, value] of m){ document.write(key," ", value,"<br>"); }
[E] 数组遍历补充
数组
for循环
for...in
forEach
for...of
对象
for...in
集合
for...of
[F] 回顾面向对象的概念
1. 历史
面向过程的编程语言:汇编语言,C语言
面向对象的编程语言:C++,Java,JavaScript, Python
2. 思想
面向过程编程思想:只关心数学逻辑
面向对象编程思想:直接将生活中的逻辑映射到程序中
1. 找出实体对象
2. 分析实体对象的属性和功能
3. 让实体之间相互作用
3. 代码
。。。
4. 语法
类:一类具有相同特征的抽象事物
对象:具体的一个示例,唯一的一个实体
5. 数据类型
基本的数据类型 => 数组(批量处理数据) => 对象(既能村塾数据,又能存储函数)
[G] 构造函数封装
构造函数封装:即封装一个可以创建对象的函数
构造函数封装
工厂模式:
1. 原料
2. 加工
3. 出厂
function createPerson(name,gender){ // 1. 原料 var obj = new Object(); // 2. 加工 obj.name = name; obj.gender = gender; obj.showName = function(){ alert("我的名字叫" + this.name); } obj.showGender = function(){ alert("我是一名" + gender + "性"); } // 3. 出厂 return obj; }
【注】凡是经过上述三步创建对象的函数,我们都把它叫做工厂方法
工厂模式创建的构造函数封装存在一些问题:
1. 没有 new 关键字
【解决】当添加new关键字创建时的变化:
a. 当前函数中的this指向新创建的对象,即函数本身
b. 自动去完成 1原料 和 3出厂 两个操作
function Person(name,gender){ // 省略步骤1.原料 // 2. 加工 this.name = name; this.gender = gender; this.showName = function(){ alert("我的名字叫" + this.name); } this.showGender = function(){ alert("我是一名" + this.gender + "性"); } // 省略步骤3.出厂 }
【注】这种通过 new关键字创建的函数,我们称之为构造函数,构造函数可以构造对象
2. 每一个新创建出的对象都独立的有一套函数系统(这不利于节省内存)
【解决】prototype 原型对象
概念:每一个函数都有一个原型对象prototype
用处:用在构造函数上,一般封装的函数上prototype无用。
prototype的使用:在构造函数的原型prototype上添加方法,该方法就会在所有通过在构造函数方法创建的对象上共享该方法。
【注】prototype方法的添加在函数体外
function Person(name,gender){ // 1. 原料 this.name = name; this.gender = gender; } Person.prototype.showName = function(){ alert("我的名字叫" + this.name); } Person.prototype.showGender = function(){ alert("我是一名" + this.gender + "性"); } var p1 = new Person("jack","男"); var p2 = new Person("jean","女"); alert(p1.showName == p1.showName); // 返回true
【注】通过上述两个方法创建的构造函数和官方创建的构造函数一样。
[H] 面向对象的继承和多态
面向对象:封装,继承,多态。
面向对象是一个编程思想,支撑面向对象编程语言的语法是类和对象。
(ECMA6之前是没有类的概念,构造函数充当类的概念)
【侧重点】
继承:从父一级的继承函数继承得到属性和方法
多态:子一级的属性和方法的更新与新增
分类更加细分的构造函数,可以通过继承父一级构造函数的属性和方法,再添加自己的属性和方法的方式进行构造
继承的存在可以节省书写代码的空间和时间
【继承的实现】:
// 创建狗对象 function Dog(name, gender, age){ this.name = name; this.gender = gender; this.age = age; } //添加狗的原型对象方法 Dog.prototype = { showName: function(){ alert("我的名字叫" + this.name); }, showGender: function(){ alert("我是一名" + this.gender + "性"); } }
//1. 泰迪继承狗的属性
function Teddy(name, gender, age, color){
// 继承
Dog.call(this,name, gender, age)
// 添加自己特有的属性
this.color = color;
}
for(var fucnName in Dog.prototype){ Teddy.prototype[funcName] = Dog.prototype[funcName]; }
Teddy.prototype.showName = function(){ alert("我的名字叫" + this.name); }
多态:通过继承得到的属性或者方法可能存在过时的问题,此时需要更新或者新增属性和方法
【更新或者新增属性和方法】直接重写一个同名属性或者函数去覆盖原属性和方法即可
[ I ] 原型详解
原型详解:
1. 构造函数构造出来的对象,都有一个 __proto__属性,指向构造出征对象的构造函数的原型。
2. instanceof 关键字
判断某一个对象是否是这个构造函数构造出来的
如:"小黑" instanceof Dog 判断小黑对象是否由Dog这个构造函数构造出来的