JavaScript高级篇
1.1 面向过程和对象
面向过程编程 POP(Process-oriented programming)
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依
次调用就可以了。
面向过程,就是按照我们分析好了的步骤,按照步骤解决问题。
优点:性能比面向对象高,适合跟硬件联系很紧密
的东西,例如单片机就采用的面向过程编程。
缺点:没有面向对象易维护、易复用、易扩展
面向对象
面向对象编程 OOP (Object Oriented Programming)
面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。
面向对象是以对象功能来划分问题,而不是步骤。
优点:易维护、易复用、易扩展,由于面向对象有
封装、继承、多态性的特性,可以设计出低耦合的
系统,使系统 更加灵活、更加易于维护
缺点:性能比面向过程低
1.2 ES6 中的类和对象
对象是由属性和方法组成的:
属性:事物的特征,在对象中用属性来表示(常用名词)
方法:事物的行为,在对象中用方法来表示(常用动词)
1.2.1 创建类和对象
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
class Star {
constructor ( uname, age) {
this . uname = uname;
this . age = age;
}
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 20 ) ;
console. log ( ldh) ;
console. log ( zxy) ;
</ script>
</ body>
</ html>
1.2.2 类中添加方法
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
class Star {
constructor ( uname, age) {
this . uname = uname;
this . age = age;
}
sing ( song) {
console. log ( this . uname + song) ;
}
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 20 ) ;
console. log ( ldh) ;
console. log ( zxy) ;
ldh. sing ( '冰雨' ) ;
zxy. sing ( '李香兰' ) ;
</ script>
</ body>
</ html>
1.2.3 类的继承
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
class Father {
constructor ( x, y) {
this . x = x;
this . y = y;
}
sum ( ) {
console. log ( this . x + this . y) ;
}
}
class Son extends Father {
constructor ( x, y) {
super ( x, y) ;
}
}
var son = new Son ( 1 , 2 ) ;
var son1 = new Son ( 11 , 22 ) ;
son. sum ( ) ;
son1. sum ( ) ;
</ script>
</ body>
</ html>
1.2.4 super关键字调用父类普通函数
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
class Father {
say ( ) {
return '我是爸爸' ;
}
}
class Son extends Father {
say ( ) {
console. log ( super . say ( ) + '的儿子' ) ;
}
}
var son = new Son ( ) ;
son. say ( ) ;
</ script>
</ body>
</ html>
1.2.5 子类继承父类方法同时扩展自己方法
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
class Father {
constructor ( x, y) {
this . x = x;
this . y = y;
}
sum ( ) {
console. log ( this . x + this . y) ;
}
}
class Son extends Father {
constructor ( x, y) {
super ( x, y) ;
this . x = x;
this . y = y;
}
subtract ( ) {
console. log ( this . x - this . y) ;
}
}
var son = new Son ( 5 , 3 ) ;
son. subtract ( ) ;
son. sum ( ) ;
</ script>
</ body>
</ html>
1.2.6 使用类注意事项
1 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象.
2 类里面的共有属性和方法一定要加this使用.
3 类里面的this指向问题.
4 constructor 里面的this指向实例对象, 方法里面的this 指向这个方法的调用者
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< button> 点击</ button>
< script>
var that;
var _that;
class Star {
constructor ( uname, age) {
that = this ;
console. log ( this ) ;
this . uname = uname;
this . age = age;
this . btn = document. querySelector ( 'button' ) ;
this . btn. onclick = this . sing;
}
sing ( ) {
console. log ( this ) ;
console. log ( that. uname) ;
}
dance ( ) {
_that = this ;
console. log ( this ) ;
}
}
var ldh = new Star ( '刘德华' ) ;
console. log ( that === ldh) ;
ldh. dance ( ) ;
console. log ( _that === ldh) ;
</ script>
</ body>
</html
1.2.7 面向对象版 tab 栏切换
功能需求:
1 点击 tab栏,可以切换效果.
2 点击 + 号, 可以添加 tab 项和内容项.
3 点击 x 号, 可以删除当前的tab项和内容项.
4 双击tab项文字或者内容项文字,可以修改里面的文字内容.
抽象对象: Tab 对象
1 该对象具有切换功能
2 该对象具有添加功能
3 该对象具有删除功能
4 该对象具有修改功能
1 点击 + 可以实现添加新的选项卡和内容
2 第一步: 创建新的选项卡li 和 新的 内容 section
3 第二步: 把创建的两个元素追加到对应的父元素中.
4 以前的做法: 动态创建元素 createElement , 但是元素里面内容较多, 需要innerHTML赋值,在 appendChild
追加到父元素里面.
5 现在高级做法: 利用 insertAdjacentHTML() 可以直接把字符串格式元素添加到父元素中
6 appendChild 不支持追加字符串的子元素, insertAdjacentHTML 支持追加字符串的元素
7 insertAdjacentHTML(追加的位置,‘要追加的字符串元素’)
8 追加的位置有: beforeend 插入元素内部的最后一个子节点之后
9 该方法地址: https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML
1 点击 × 可以删除当前的li选项卡和当前的section
2 X是没有索引号的, 但是它的父亲li 有索引号, 这个索引号正是我们想要的索引号
3 所以核心思路是: 点击 x 号可以删除这个索引号对应的 li 和 section
4 但是,当我们动态删除新的li和索引号时,也需要重新获取 x 这个元素. 需要调用init 方法
1 双击选项卡li或者 section里面的文字,可以实现修改功能
2 双击事件是: ondblclick
3 如果双击文字,会默认选定文字,此时需要双击禁止选中文字
4 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
5 核心思路: 双击文字的时候, 在 里面生成一个文本框, 当失去焦点或者按下回车然后把文本框输入的值给原先
元素即可.
tab.js
var that;
class Tab {
constructor(id) {
// 获取元素
that = this;
this.main = document.querySelector(id);
this.add = this.main.querySelector('.tabadd');
// li的父元素
this.ul = this.main.querySelector('.fisrstnav ul:first-child');
// section 父元素
this.fsection = this.main.querySelector('.tabscon');
this.init();
}
init() {
this.updateNode();
// init 初始化操作让相关的元素绑定事件
this.add.onclick = this.addTab;
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].index = i;
this.lis[i].onclick = this.toggleTab;
this.remove[i].onclick = this.removeTab;
this.spans[i].ondblclick = this.editTab;
this.sections[i].ondblclick = this.editTab;
}
}
// 因为我们动态添加元素 需要从新获取对应的元素
updateNode() {
this.lis = this.main.querySelectorAll('li');
this.sections = this.main.querySelectorAll('section');
this.remove = this.main.querySelectorAll('.icon-guanbi');
this.spans = this.main.querySelectorAll('.fisrstnav li span:first-child');
}
// 1. 切换功能
toggleTab() {
// console.log(this.index);
that.clearClass();
this.className = 'liactive';
that.sections[this.index].className = 'conactive';
}
// 清除所有li 和section 的类
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 2. 添加功能
addTab() {
that.clearClass();
// (1) 创建li元素和section元素
var random = Math.random();
var li = '< li class = " liactive" > < span> 新选项卡</ span> < span class = " iconfont icon-guanbi" > </ span> </ li> ';
var section = '< section class = " conactive" > 测试 ' + random + '</ section> ';
// (2) 把这两个元素追加到对应的父元素里面
that.ul.insertAdjacentHTML('beforeend', li);
that.fsection.insertAdjacentHTML('beforeend', section);
that.init();
}
// 3. 删除功能
removeTab(e) {
e.stopPropagation(); // 阻止冒泡 防止触发li 的切换点击事件
var index = this.parentNode.index;
console.log(index);
// 根据索引号删除对应的li 和section remove()方法可以直接删除指定的元素
that.lis[index].remove();
that.sections[index].remove();
that.init();
// 当我们删除的不是选中状态的li 的时候,原来的选中状态li保持不变
if (document.querySelector('.liactive')) return;
// 当我们删除了选中状态的这个li 的时候, 让它的前一个li 处于选定状态
index--;
// 手动调用我们的点击事件 不需要鼠标触发
that.lis[index] && that.lis[index].click();
}
// 4. 修改功能
editTab() {
var str = this.innerHTML;
// 双击禁止选定文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
// alert(11);
this.innerHTML = '< input type = " text" /> ';
var input = this.children[0];
input.value = str;
input.select(); // 文本框里面的文字处于选定状态
// 当我们离开文本框就把文本框里面的值给span
input.onblur = function() {
this.parentNode.innerHTML = this.value;
};
// 按下回车也可以把文本框里面的值给span
input.onkeyup = function(e) {
if (e.keyCode === 13) {
// 手动调用表单失去焦点事件 不需要鼠标离开操作
this.blur();
}
}
}
}
new Tab('#tab');
index.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> 面向对象 Tab</ title>
< link rel = " stylesheet" href = " ./styles/tab.css" >
< link rel = " stylesheet" href = " ./styles/style.css" >
</ head>
< body>
< main>
< h4>
Js 面向对象 动态添加标签页
</ h4>
< div class = " tabsbox" id = " tab" >
< nav class = " fisrstnav" >
< ul>
< li class = " liactive" > < span> 测试1</ span> < span class = " iconfont icon-guanbi" > </ span> </ li>
< li> < span> 测试2</ span> < span class = " iconfont icon-guanbi" > </ span> </ li>
< li> < span> 测试3</ span> < span class = " iconfont icon-guanbi" > </ span> </ li>
</ ul>
< div class = " tabadd" >
< span> +</ span>
</ div>
</ nav>
< div class = " tabscon" >
< section class = " conactive" > 测试1</ section>
< section> 测试2</ section>
< section> 测试3</ section>
</ div>
</ div>
</ main>
< script src = " js/tab.js" > </ script>
</ body>
</ html>
1.2.8 构造函数和原型
在典型的 OOP 的语言中(如 Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在 ES6之前,
JS 中并没用引入类的概念。
ES6, 全称 ECMAScript 6.0 ,2015.06 发版。但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏
览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。
在 ES6之前 ,对象不是基于类创建的,而是用一种称为构建函数的特殊函数来定义对象和它们的特征。
创建对象可以通过以下三种方式:
1 对象字面量
2 new Object()
3 自定义构造函数
1.2.8.1 利用构造函数创建对象
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 一起使用。我
们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
1.2 构造函数
在 JS 中,使用构造函数时要注意以下两点:
1. 构造函数用于创建某一类对象,其首字母要大写
2. 构造函数要和 new 一起使用才有意义
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var obj1 = new Object ( ) ;
var obj2 = {
} ;
function Star ( uname, age) {
this . uname = uname;
this . age = age;
this . sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 19 ) ;
console. log ( ldh) ;
ldh. sing ( ) ;
zxy. sing ( ) ;
</ script>
</ body>
</ html>
1.2.8.2 静态成员和实例成员
JavaScript 的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添
加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。
静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
this . sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
}
var ldh = new Star ( '刘德华' , 18 ) ;
console. log ( ldh. uname) ;
ldh. sing ( ) ;
Star. sex = '男' ;
console. log ( Star. sex) ;
console. log ( ldh. sex) ;
</ script>
</ body>
</ html>
1.2.8.3 构造函数原型 prototype
构造函数通过原型分配的函数是所有对象所共享的。
JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。注意这个 prototype 就是一
个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
}
Star. prototype. sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 19 ) ;
console. log ( ldh. sing === zxy. sing) ;
ldh. sing ( ) ;
zxy. sing ( ) ;
</ script>
</ body>
</ html>
1.2.8.4 对象原型 proto
对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数
prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。
__proto__对象原型和原型对象 prototype 是等价的
__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,
因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
}
Star. prototype. sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 19 ) ;
ldh. sing ( ) ;
console. log ( ldh) ;
console. log ( ldh. __proto__ === Star. prototype) ;
</ script>
</ body>
</ html>
1.2.8.5 原型constructor
对象原型( __proto__)和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称
为构造函数,因为它指回构造函数本身。
constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋
值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。
此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
}
Star. prototype = {
constructor: Star,
sing: function ( ) {
console. log ( '我会唱歌' ) ;
} ,
movie: function ( ) {
console. log ( '我会演电影' ) ;
}
}
var ldh = new Star ( '刘德华' , 18 ) ;
var zxy = new Star ( '张学友' , 19 ) ;
console. log ( Star. prototype) ;
console. log ( ldh. __proto__) ;
console. log ( Star. prototype. constructor) ;
console. log ( ldh. __proto__. constructor) ;
</ script>
</ body>
</ html>
1.2.8.6 构造函数、实例、原型对象三者之间的关系
1.2.8.7 原型链
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
}
Star. prototype. sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
var ldh = new Star ( '刘德华' , 18 ) ;
console. log ( Star. prototype) ;
console. log ( Star. prototype. __proto__ === Object. prototype) ;
console. log ( Object. prototype. __proto__) ;
</ script>
</ body>
</ html>
1.2.8.8 JavaScript 的成员查找机制
① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
③ 如果还没有就查找原型对象的原型(Object的原型对象)。
④ 依此类推一直找到 Object 为止(null)。
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Star ( uname, age) {
this . uname = uname;
this . age = age;
}
Star. prototype. sing = function ( ) {
console. log ( '我会唱歌' ) ;
}
Star. prototype. sex = '女' ;
var ldh = new Star ( '刘德华' , 18 ) ;
ldh. sex = '男' ;
console. log ( ldh. sex) ;
console. log ( Object. prototype) ;
console. log ( ldh) ;
console. log ( Star. prototype) ;
console. log ( ldh. toString ( ) ) ;
</ script>
</ body>
</ html>
1.2.8.9 原型对象this指向
构造函数中的this 指向我们实例对象.
原型对象里面放的是方法, 这个方法里面的this 指向的是 这个方法的调用者, 也就是这个实例对象.
1.2.8.10 扩展内置对象
可以通过原型对象,对原来的内置对象进行扩展自定义的方法。比如给数组增加自定义求偶数和的功能。
注意:数组和字符串内置对象不能给原型对象覆盖操作 Array.prototype = {} ,只能是 Array.prototype.xxx = function(){} 的方式。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
Array. prototype. sum = function ( ) {
var sum = 0 ;
for ( var i = 0 ; i < this . length; i++ ) {
sum += this [ i] ;
}
return sum;
} ;
var arr = [ 1 , 2 , 3 ] ;
console. log ( arr. sum ( ) ) ;
console. log ( Array. prototype) ;
var arr1 = new Array ( 11 , 22 , 33 ) ;
console. log ( arr1. sum ( ) ) ;
</ script>
</ body>
</ html>
1.2.9 继承
ES6之前并没有给我们提供 extends 继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
1.2.9.1 call方法
调用这个函数, 并且修改函数运行时的 this 指向
fun.call(thisArg, arg1, arg2, ...)
thisArg :当前调用函数 this 的指向对象
arg1,arg2:传递的其他参数
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( x, y) {
console. log ( '我想喝手磨咖啡' ) ;
console. log ( this ) ;
console. log ( x + y) ;
}
var o = {
name: 'andy'
} ;
fn. call ( o, 1 , 2 ) ;
</ script>
</ body>
</ html>
1.2.9.2 借用父构造函数继承属性
核心原理: 通过 call() 把父类型的 this 指向子类型的 this ,这样就可以实现子类型继承父类型的属性
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Father ( uname, age) {
this . uname = uname;
this . age = age;
}
function Son ( uname, age, score) {
Father. call ( this , uname, age) ;
this . score = score;
}
var son = new Son ( '刘德华' , 18 , 100 ) ;
console. log ( son) ;
</ script>
</ body>
</ html>
1.2.9.3 借用原型对象继承方法
一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类方法。
核心原理:
1 将子类所共享的方法提取出来,让子类的 prototype 原型对象 = new 父类()
2 本质:子类原型对象等于是实例化父类,因为父类实例化之后另外开辟空间,就不会影响原来父类原型对象
3 将子类的 constructor 从新指向子类的构造函数
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function Father ( uname, age) {
this . uname = uname;
this . age = age;
}
Father. prototype. money = function ( ) {
console. log ( 100000 ) ;
} ;
function Son ( uname, age, score) {
Father. call ( this , uname, age) ;
this . score = score;
}
Son. prototype = new Father ( ) ;
Son. prototype. constructor = Son;
Son. prototype. exam = function ( ) {
console. log ( '孩子要考试' ) ;
}
var son = new Son ( '刘德华' , 18 , 100 ) ;
console. log ( son) ;
console. log ( Father. prototype) ;
console. log ( Son. prototype. constructor) ;
</ script>
</ body>
</ html>
1.2.10 ES5 中的新增方法
ES5 中给我们新增了一些方法,可以很方便的操作数组或者字符串,这些方法主要包括:
数组方法
字符串方法
对象方法
1.2.10.1 数组方法
迭代(遍历)方法:forEach()、map()、filter()、some()、every();
1.2.10.1.1 forEach方法
array.forEach(function(currentValue, index, arr))
currentValue:数组当前项的值
index:数组当前项的索引
arr:数组对象本身
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var arr = [ 1 , 2 , 3 ] ;
var sum = 0 ;
arr. forEach ( function ( value, index, array) {
console. log ( '每个数组元素' + value) ;
console. log ( '每个数组元素的索引号' + index) ;
console. log ( '数组本身' + array) ;
sum += value;
} )
console. log ( sum) ;
</ script>
</ body>
</ html>
1.2.10.1.2 filter筛选数组
array.filter(function(currentValue, index, arr))
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组
注意它直接返回一个新数组
currentValue: 数组当前项的值
index:数组当前项的索引
arr:数组对象本身
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var arr = [ 12 , 66 , 4 , 88 , 3 , 7 ] ;
var newArr = arr. filter ( function ( value, index) {
return value % 2 === 0 ;
} ) ;
console. log ( newArr) ;
</ script>
</ body>
</ html>
1.2.10.1.3 some查找数组中是否有满足条件的元素
array.some(function(currentValue, index, arr))
some() 方法用于检测数组中的元素是否满足指定条件. 通俗点 查找数组中是否有满足条件的元素
注意它返回值是布尔值, 如果查找到这个元素, 就返回true , 如果查找不到就返回false.
如果找到第一个满足条件的元素,则终止循环. 不在继续查找.
currentValue: 数组当前项的值
index:数组当前项的索引
arr:数组对象本身
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var arr1 = [ 'red' , 'pink' , 'blue' ] ;
var flag1 = arr1. some ( function ( value) {
return value == 'pink' ;
} ) ;
console. log ( flag1) ;
</ script>
</ body>
</ html>
1.2.10.1.4 查询商品案例
1. 把数据渲染到页面中 (forEach)
2. 根据价格显示数据
3. 根据商品名称显示数据
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
< style>
table {
width : 400px;
border : 1px solid #000;
border-collapse : collapse;
margin : 0 auto;
}
td,
th {
border : 1px solid #000;
text-align : center;
}
input {
width : 50px;
}
.search {
width : 600px;
margin : 20px auto;
}
</ style>
</ head>
< body>
< div class = " search" >
按照价格查询: < input type = " text" class = " start" > - < input type = " text" class = " end" > < button class = " search-price" > 搜索</ button> 按照商品名称查询: < input type = " text" class = " product" > < button class = " search-pro" > 查询</ button>
</ div>
< table>
< thead>
< tr>
< th> id</ th>
< th> 产品名称</ th>
< th> 价格</ th>
</ tr>
</ thead>
< tbody>
</ tbody>
</ table>
< script>
var data = [ {
id: 1 ,
pname: '小米' ,
price: 3999
} , {
id: 2 ,
pname: 'oppo' ,
price: 999
} , {
id: 3 ,
pname: '荣耀' ,
price: 1299
} , {
id: 4 ,
pname: '华为' ,
price: 1999
} , ] ;
var tbody = document. querySelector ( 'tbody' ) ;
var search_price = document. querySelector ( '.search-price' ) ;
var start = document. querySelector ( '.start' ) ;
var end = document. querySelector ( '.end' ) ;
var product = document. querySelector ( '.product' ) ;
var search_pro = document. querySelector ( '.search-pro' ) ;
setDate ( data) ;
function setDate ( mydata) {
tbody. innerHTML = '' ;
mydata. forEach ( function ( value) {
var tr = document. createElement ( 'tr' ) ;
tr. innerHTML = '<td>' + value. id + '</td><td>' + value. pname + '</td><td>' + value. price + '</td>' ;
tbody. appendChild ( tr) ;
} ) ;
}
search_price. addEventListener ( 'click' , function ( ) {
var newDate = data. filter ( function ( value) {
return value. price >= start. value && value. price <= end. value;
} ) ;
console. log ( newDate) ;
setDate ( newDate) ;
} ) ;
search_pro. addEventListener ( 'click' , function ( ) {
var arr = [ ] ;
data. some ( function ( value) {
if ( value. pname === product. value) {
arr. push ( value) ;
return true ;
}
} ) ;
setDate ( arr) ;
} )
</ script>
</ body>
</ html>
1.2.10.1.5 forEach和some区别
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var arr = [ 'red' , 'green' , 'blue' , 'pink' ] ;
arr. some ( function ( value) {
if ( value == 'green' ) {
console. log ( '找到了该元素' ) ;
return true ;
}
console. log ( 11 ) ;
} ) ;
</ script>
</ body>
</ html>
1.2.11 字符串方法
trim() 方法会从一个字符串的两端删除空白字符。
str.trim()
trim() 方法并不影响原字符串本身,它返回的是一个新的字符串。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< input type = " text" > < button> 点击</ button>
< div> </ div>
< script>
var str = ' an dy ' ;
console. log ( str) ;
var str1 = str. trim ( ) ;
console. log ( str1) ;
var input = document. querySelector ( 'input' ) ;
var btn = document. querySelector ( 'button' ) ;
var div = document. querySelector ( 'div' ) ;
btn. onclick = function ( ) {
var str = input. value. trim ( ) ;
if ( str === '' ) {
alert ( '请输入内容' ) ;
} else {
console. log ( str) ;
console. log ( str. length) ;
div. innerHTML = str;
}
}
</ script>
</ body>
</ html>
1.2.11.1 对象方法
Object.keys() 方法返回一个所有元素为字符串的数组。
Object.keys(obj)
效果类似 for…in
Object.defineProperty() 定义新属性或修改原有的属性。
Object.defineProperty(obj, prop, descriptor)
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性
Object.defineProperty() 第三个参数 descriptor 说明:
value: 设置属性的值
writable: 值是否可以重写。true | false
enumerable: 目标属性是否可以被枚举。true | false
configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false
1.2.11.2 Object.keys遍历对象属性
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var obj = {
id: 1 ,
pname: '小米' ,
price: 1999 ,
num: 2000
} ;
var arr = Object. keys ( obj) ;
console. log ( arr) ;
arr. forEach ( function ( value) {
console. log ( value) ;
} )
</ script>
</ body>
</ html>
1.2.11.3 Object.defineProperty方法
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var obj = {
id: 1 ,
pname: '小米' ,
price: 1999
} ;
Object. defineProperty ( obj, 'num' , {
value: 1000 ,
enumerable: true
} ) ;
console. log ( obj) ;
Object. defineProperty ( obj, 'price' , {
value: 9.9
} ) ;
console. log ( obj) ;
Object. defineProperty ( obj, 'id' , {
writable: false ,
} ) ;
obj. id = 2 ;
console. log ( obj) ;
Object. defineProperty ( obj, 'address' , {
value: '中国山东蓝翔技校xx单元' ,
writable: false ,
enumerable: false ,
configurable: false
} ) ;
console. log ( obj) ;
console. log ( Object. keys ( obj) ) ;
delete obj. address;
console. log ( obj) ;
delete obj. pname;
console. log ( obj) ;
Object. defineProperty ( obj, 'address' , {
value: '中国山东蓝翔技校xx单元' ,
writable: true ,
enumerable: true ,
configurable: true
} ) ;
console. log ( obj. address) ;
</ script>
</ body>
</ html>
2.1 函数进阶
2.1.1 函数的定义
1 函数声明方式 function 关键字 (命名函数)
2 函数表达式 (匿名函数)
3 new Function()
var fn = new Function('参数1','参数2'..., '函数体')
Function 里面参数都必须是字符串格式
第三种方式执行效率低,也不方便书写,因此较少使用
所有函数都是 Function 的实例(对象)
函数也属于对象
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( ) {
} ;
var fun = function ( ) {
} ;
var f = new Function ( 'a' , 'b' , 'console.log(a + b)' ) ;
f ( 1 , 2 ) ;
console. dir ( f) ;
console. log ( f instanceof Object ) ;
</ script>
</ body>
</ html>
2.1.2 函数的调用
1 普通函数
2 对象的方法
3 构造函数
4 绑定事件函数
5 定时器函数
6 立即执行函数
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( ) {
console. log ( '人生的巅峰' ) ;
}
var o = {
sayHi: function ( ) {
console. log ( '人生的巅峰' ) ;
}
}
o. sayHi ( ) ;
function Star ( ) {
} ;
new Star ( ) ;
( function ( ) {
console. log ( '人生的巅峰' ) ;
} ) ( ) ;
</ script>
</ body>
</ html>
2.1.3 函数内 this 的指向
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< button> 点击</ button>
< script>
function fn ( ) {
console. log ( '普通函数的this' + this ) ;
}
window. fn ( ) ;
var o = {
sayHi: function ( ) {
console. log ( '对象方法的this:' + this ) ;
}
}
o. sayHi ( ) ;
function Star ( ) {
} ;
Star. prototype. sing = function ( ) {
}
var ldh = new Star ( ) ;
var btn = document. querySelector ( 'button' ) ;
btn. onclick = function ( ) {
console. log ( '绑定时间函数的this:' + this ) ;
} ;
window. setTimeout ( function ( ) {
console. log ( '定时器的this:' + this ) ;
} , 1000 ) ;
( function ( ) {
console. log ( '立即执行函数的this' + this ) ;
} ) ( ) ;
</ script>
</ body>
</ html>
2.1.4 改变函数内this指向call方法
1. call 方法
call() 方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。
fun.call(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值
arg1,arg2:传递的其他参数
返回值就是函数的返回值,因为它就是调用函数
因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var o = {
name: 'andy'
}
function fn ( a, b) {
console. log ( this ) ;
console. log ( a + b) ;
} ;
fn. call ( o, 1 , 2 ) ;
function Father ( uname, age, sex) {
this . uname = uname;
this . age = age;
this . sex = sex;
}
function Son ( uname, age, sex) {
Father. call ( this , uname, age, sex) ;
}
var son = new Son ( '刘德华' , 18 , '男' ) ;
console. log ( son) ;
</ script>
</ body>
</ html>
2.1.5 改变函数内this指向apply方法
apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。
fun.apply(thisArg, [argsArray])
thisArg:在fun函数运行时指定的 this 值
argsArray:传递的值,必须包含在数组里面
返回值就是函数的返回值,因为它就是调用函数
因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
2.1.6 改变函数内this指向bind方法
bind() 方法不会调用函数。但是能改变函数内部this 指向
fun.bind(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值
arg1,arg2:传递的其他参数
返回由指定的 this 值和初始化参数改造的原函数拷贝
因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< button> 点击</ button>
< button> 点击</ button>
< button> 点击</ button>
< script>
var o = {
name: 'andy'
} ;
function fn ( a, b) {
console. log ( this ) ;
console. log ( a + b) ;
} ;
var f = fn. bind ( o, 1 , 2 ) ;
f ( ) ;
var btns = document. querySelectorAll ( 'button' ) ;
for ( var i = 0 ; i < btns. length; i++ ) {
btns[ i] . onclick = function ( ) {
this . disabled = true ;
setTimeout ( function ( ) {
this . disabled = false ;
} . bind ( this ) , 2000 ) ;
}
}
</ script>
</ body>
</ html>
2.1.7 call apply bind 总结
相同点:
都可以改变函数内部的this指向.
区别点:
1. call 和 apply 会调用函数, 并且改变函数内部this指向.
2. call 和 apply 传递的参数不一样, call 传递参数 aru1, aru2..形式 apply 必须数组形式[arg]
3. bind 不会调用函数, 可以改变函数内部this指向.
主要应用场景:
1. call 经常做继承.
2. apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.
2.1.8 严格模式
JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性
JavaScript 变体的一种方式,即在严格的条件下运行 JS 代码。
严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。
严格模式对正常的 JavaScript 语义做了一些更改:
1 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
2 消除代码运行的一些不安全之处,保证代码运行的安全。
3 提高编译器效率,增加运行速度。
4 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比
如一些保留字如:class, enum, export, extends, import, super 不能做变量名
2.1.9 开启严格模式
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式和
为函数开启严格模式两种情况。
为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句“use strict”;(或‘use strict’;)。
有的 script 基本是严格模式,有的 script 脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件
放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他 script 脚本文件。
要给某个函数开启严格模式,需要把“use strict”; (或 'use strict'; ) 声明放在函数体所有语句之前
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
'use strict' ;
</ script>
< script>
( function ( ) {
'use strict' ;
} ) ( ) ;
</ script>
< script>
function fn ( ) {
'use strict' ;
}
function fun ( ) {
}
</ script>
</ body>
</ html>
2.1.10 严格模式中的变化
1 变量规定
1 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用
var 命令声明,然后再使用。
2 严禁删除已经声明变量。例如,delete x; 语法是错误的。
2 严格模式下 this 指向问题
1 以前在全局作用域函数中的 this 指向 window 对象。
2 严格模式下全局作用域中函数中的 this 是 undefined。
3 以前构造函数时不加 new也可以 调用,当普通函数,this 指向全局对象
4 严格模式下,如果 构造函数不加new调用, this 指向的是undefined 如果给他赋值则 会报错
5 new 实例化的构造函数指向创建的对象实例。
6 定时器 this 还是指向 window 。
7 事件、对象还是指向调用者。
3 函数变化
1 函数不能有重名的参数。
2 函数必须声明在顶层.新版本的 JavaScript 会引入“块级作用域”( ES6 中已引入)。为了与新版本接轨,
不允许在非函数的代码块内声明函数。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
'use strict' ;
var num = 10 ;
console. log ( num) ;
function fn ( ) {
}
</ script>
</ body>
</ html>
2.1.11 高阶函数
高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
< script src = " jquery.min.js" > </ script>
< style>
div {
position : absolute;
width : 100px;
height : 100px;
background-color : pink;
}
</ style>
</ head>
< body>
< div> </ div>
< script>
function fn ( a, b, callback) {
console. log ( a + b) ;
callback && callback ( ) ;
}
fn ( 1 , 2 , function ( ) {
console. log ( '我是最后调用的' ) ;
} ) ;
$ ( "div" ) . animate ( {
left: 500
} , function ( ) {
$ ( "div" ) . css ( "backgroundColor" , "purple" ) ;
} )
</ script>
</ body>
</ html>
2.1.12 闭包
变量根据作用域的不同分为两种:全局变量和局部变量。
1 函数内部可以使用全局变量。
2 函数外部不可以使用局部变量。
3 当函数执行完毕,本作用域内的局部变量会销毁。
闭包(closure)指有权访问另一个函数作用域中变量的函数。 ----- JavaScript 高级程序设计
简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。
延伸变量的作用范围
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( ) {
var num = 10 ;
function fun ( ) {
console. log ( num) ;
}
fun ( ) ;
}
fn ( ) ;
</ script>
</ body>
</ html>
2.1.13 闭包的作用
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( ) {
var num = 10 ;
return function ( ) {
console. log ( num) ;
}
}
var f = fn ( ) ;
f ( ) ;
</ script>
</ body>
</ html>
2.1.14 闭包应用-点击li输出索引号
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< ul class = " nav" >
< li> 榴莲</ li>
< li> 臭豆腐</ li>
< li> 鲱鱼罐头</ li>
< li> 大猪蹄子</ li>
</ ul>
< script>
var lis = document. querySelector ( '.nav' ) . querySelectorAll ( 'li' ) ;
for ( var i = 0 ; i < lis. length; i++ ) {
lis[ i] . index = i;
lis[ i] . onclick = function ( ) {
console. log ( this . index) ;
}
}
for ( var i = 0 ; i < lis. length; i++ ) {
( function ( i) {
lis[ i] . onclick = function ( ) {
console. log ( i) ;
}
} ) ( i) ;
}
</ script>
</ body>
</ html>
2.1.15 闭包应用-定时器中的闭包
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< ul class = " nav" >
< li> 榴莲</ li>
< li> 臭豆腐</ li>
< li> 鲱鱼罐头</ li>
< li> 大猪蹄子</ li>
</ ul>
< script>
var lis = document. querySelector ( '.nav' ) . querySelectorAll ( 'li' ) ;
for ( var i = 0 ; i < lis. length; i++ ) {
( function ( i) {
setTimeout ( function ( ) {
console. log ( lis[ i] . innerHTML) ;
} , 3000 )
} ) ( i) ;
}
</ script>
</ body>
</ html>
2.1.16 闭包应用-打车价格
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var car = ( function ( ) {
var start = 13 ;
var total = 0 ;
return {
price: function ( n) {
if ( n <= 3 ) {
total = start;
} else {
total = start + ( n - 3 ) * 5
}
return total;
} ,
yd: function ( flag) {
return flag ? total + 10 : total;
}
}
} ) ( ) ;
console. log ( car. price ( 5 ) ) ;
console. log ( car. yd ( true ) ) ;
console. log ( car. price ( 1 ) ) ;
console. log ( car. yd ( false ) ) ;
</ script>
</ body>
</ html>
2.1.17 递归函数
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var num = 1 ;
function fn ( ) {
console. log ( '我要打印6句话' ) ;
if ( num == 6 ) {
return ;
}
num++ ;
fn ( ) ;
}
fn ( ) ;
</ script>
</ body>
</ html>
2.1.18 利用递归求1~n的阶乘
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fn ( n) {
if ( n == 1 ) {
return 1 ;
}
return n * fn ( n - 1 ) ;
}
console. log ( fn ( 3 ) ) ;
console. log ( fn ( 4 ) ) ;
</ script>
</ body>
</ html>
2.1.19 利用递归函数求斐波那契数列
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
function fb ( n) {
if ( n === 1 || n === 2 ) {
return 1 ;
}
return fb ( n - 1 ) + fb ( n - 2 ) ;
}
console. log ( fb ( 3 ) ) ;
console. log ( fb ( 6 ) ) ;
</ script>
</ body>
</ html>
2.1.20 利用递归遍历数据
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var data = [ {
id: 1 ,
name: '家电' ,
goods: [ {
id: 11 ,
gname: '冰箱' ,
goods: [ {
id: 111 ,
gname: '海尔'
} , {
id: 112 ,
gname: '美的'
} , ]
} , {
id: 12 ,
gname: '洗衣机'
} ]
} , {
id: 2 ,
name: '服饰'
} ] ;
function getID ( json, id) {
var o = {
} ;
json. forEach ( function ( item) {
if ( item. id == id) {
o = item;
} else if ( item. goods && item. goods. length > 0 ) {
o = getID ( item. goods, id) ;
}
} ) ;
return o;
}
console. log ( getID ( data, 1 ) ) ;
console. log ( getID ( data, 2 ) ) ;
console. log ( getID ( data, 11 ) ) ;
console. log ( getID ( data, 12 ) ) ;
console. log ( getID ( data, 111 ) ) ;
</ script>
</ body>
</ html>
2.1.21 浅拷贝
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var obj = {
id: 1 ,
name: 'andy' ,
msg: {
age: 18
}
} ;
var o = {
} ;
console. log ( '--------------' ) ;
Object. assign ( o, obj) ;
console. log ( o) ;
o. msg. age = 20 ;
console. log ( obj) ;
</ script>
</ body>
</ html>
2.1.22 深拷贝
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
</ head>
< body>
< script>
var obj = {
id: 1 ,
name: 'andy' ,
msg: {
age: 18
} ,
color: [ 'pink' , 'red' ]
} ;
var o = {
} ;
function deepCopy ( newobj, oldobj) {
for ( var k in oldobj) {
var item = oldobj[ k] ;
if ( item instanceof Array ) {
newobj[ k] = [ ] ;
deepCopy ( newobj[ k] , item)
} else if ( item instanceof Object ) {
newobj[ k] = {
} ;
deepCopy ( newobj[ k] , item)
} else {
newobj[ k] = item;
}
}
}
deepCopy ( o, obj) ;
console. log ( o) ;
var arr = [ ] ;
console. log ( arr instanceof Object ) ;
o. msg. age = 20 ;
console. log ( obj) ;
</ script>
</ body>
</ html>
3.1 正则表达式
正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。
正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
3.1.1 正则表达式在js在使用
1 利用 RegExp对象来创建 正则表达式
var regexp = new RegExp(/123/);
2 利用字面量创建 正则表达式
var rg = /123/;
3 test 方法用来检测字符串是否符合正则表达式要求的规范
console.log(rg.test(123));
< script>
var regexp = new RegExp ( /123/ ) ;
console. log ( regexp) ;
var rg = /123/ ;
console. log ( rg. test ( 123 ) ) ;
console. log ( rg. test ( 'abc' ) ) ;
</ script>
3.1.2 正则表达式中的特殊字符
3.1.2.1 边界符
正则表达式里面不需要加引号 不管是数字型还是字符串型
< script>
var rg = /abc/ ;
console. log ( rg. test ( 'abc' ) ) ;
console. log ( rg. test ( 'abcd' ) ) ;
console. log ( rg. test ( 'aabcd' ) ) ;
console. log ( '---------------------------' ) ;
var reg = /^abc/ ;
console. log ( reg. test ( 'abc' ) ) ;
console. log ( reg. test ( 'abcd' ) ) ;
console. log ( reg. test ( 'aabcd' ) ) ;
console. log ( '---------------------------' ) ;
var reg1 = /^abc$/ ;
console. log ( reg1. test ( 'abc' ) ) ;
console. log ( reg1. test ( 'abcd' ) ) ;
console. log ( reg1. test ( 'aabcd' ) ) ;
console. log ( reg1. test ( 'abcabc' ) ) ;
</ script>
3.1.2.2 字符类
[] 表示有一系列字符可供选择,只要匹配其中一个就可以了
[-] 方括号内部加上 - 表示范围
[^] 方括号内部 取反符^
< script>
var rg = /[abc]/ ;
console. log ( rg. test ( 'andy' ) ) ;
console. log ( rg. test ( 'baby' ) ) ;
console. log ( rg. test ( 'color' ) ) ;
console. log ( rg. test ( 'red' ) ) ;
var rg1 = /^[abc]$/ ;
console. log ( rg1. test ( 'aa' ) ) ;
console. log ( rg1. test ( 'a' ) ) ;
console. log ( rg1. test ( 'b' ) ) ;
console. log ( rg1. test ( 'c' ) ) ;
console. log ( rg1. test ( 'abc' ) ) ;
console. log ( '------------------' ) ;
var reg = /^[a-z]$/ ;
console. log ( reg. test ( 'a' ) ) ;
console. log ( reg. test ( 'z' ) ) ;
console. log ( reg. test ( 1 ) ) ;
console. log ( reg. test ( 'A' ) ) ;
var reg1 = /^[a-zA-Z0-9_-]$/ ;
console. log ( reg1. test ( 'a' ) ) ;
console. log ( reg1. test ( 'B' ) ) ;
console. log ( reg1. test ( 8 ) ) ;
console. log ( reg1. test ( '-' ) ) ;
console. log ( reg1. test ( '_' ) ) ;
console. log ( reg1. test ( '!' ) ) ;
console. log ( '----------------' ) ;
var reg2 = /^[^a-zA-Z0-9_-]$/ ;
console. log ( reg2. test ( 'a' ) ) ;
console. log ( reg2. test ( 'B' ) ) ;
console. log ( reg2. test ( 8 ) ) ;
console. log ( reg2. test ( '-' ) ) ;
console. log ( reg2. test ( '_' ) ) ;
console. log ( reg2. test ( '!' ) ) ;
</ script>
3.1.2.3 量词
< script>
var reg = /^a{3,}$/ ;
console. log ( reg. test ( '' ) ) ;
console. log ( reg. test ( 'a' ) ) ;
console. log ( reg. test ( 'aa' ) ) ;
console. log ( reg. test ( 'aaaaaa' ) ) ;
console. log ( reg. test ( 'aaa' ) ) ;
var reg = /^a{3,16}$/ ;
console. log ( reg. test ( '' ) ) ;
console. log ( reg. test ( 'a' ) ) ;
console. log ( reg. test ( 'aa' ) ) ;
console. log ( reg. test ( 'aaaaaa' ) ) ;
console. log ( reg. test ( 'aaa' ) ) ;
console. log ( reg. test ( 'aaaaaaaaaaaaaaaaaaaaa' ) ) ;
</ script>
3.1.2.4 用户名验证
功能需求:
1. 如果用户名输入合法, 则后面提示信息为 : 用户名合法,并且颜色为绿色
2. 如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为绿色
分析:
1. 用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为 6~16位.
2. 首先准备好这种正则表达式模式 /$[a-zA-Z0-9-_]{6,16}^/
3. 当表单失去焦点就开始验证.
4. 如果符合正则规范, 则让后面的span标签添加 right 类.
5. 如果不符合正则规范, 则让后面的span标签添加 wrong 类.
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
< style>
span {
color : #aaa;
font-size : 14px;
}
.right {
color : green;
}
.wrong {
color : red;
}
</ style>
</ head>
< body>
< input type = " text" class = " uname" > < span> 请输入用户名</ span>
< script>
var reg = /^[a-zA-Z0-9_-]{6,16}$/ ;
var uname = document. querySelector ( '.uname' ) ;
var span = document. querySelector ( 'span' ) ;
uname. onblur = function ( ) {
if ( reg. test ( this . value) ) {
console. log ( '正确的' ) ;
span. className = 'right' ;
span. innerHTML = '用户名格式输入正确' ;
} else {
console. log ( '错误的' ) ;
span. className = 'wrong' ;
span. innerHTML = '用户名格式输入不正确' ;
}
}
</ script>
</ body>
</ html>
3.1.2.5 括号总结
1. 大括号{} 量词符. 里面表示重复次数
2. 中括号[] 字符集合。匹配方括号中的任意字符.
3. 小括号 ()表示优先级
3.1.2.5.1 预定义类
3.1.2.5.2 表单验证
reg.js
window.onload = function() {
var regtel = /^1[3|4|5|7|8]\d{9}$/; // 手机号码的正则表达式
var regqq = /^[1-9]\d{4,}$/; // 10000
var regnc = /^[\u4e00-\u9fa5]{2,8}$/;
var regmsg = /^\d{6}$/;
var regpwd = /^[a-zA-Z0-9_-]{6,16}$/;
var tel = document.querySelector('#tel');
var qq = document.querySelector('#qq');
var nc = document.querySelector('#nc');
var msg = document.querySelector('#msg');
var pwd = document.querySelector('#pwd');
var surepwd = document.querySelector('#surepwd');
regexp(tel, regtel); // 手机号码
regexp(qq, regqq); // qq号码
regexp(nc, regnc); // 昵称
regexp(msg, regmsg); // 短信验证
regexp(pwd, regpwd); // 密码框
// 表单验证的函数
function regexp(ele, reg) {
ele.onblur = function() {
if (reg.test(this.value)) {
// console.log('正确的');
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '< i class = " success_icon" > </ i> 恭喜您输入正确';
} else {
// console.log('不正确');
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '< i class = " error_icon" > </ i> 格式不正确,请从新输入 ';
}
}
};
surepwd.onblur = function() {
if (this.value == pwd.value) {
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '< i class = " success_icon" > </ i> 恭喜您输入正确';
} else {
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '< i class = " error_icon" > </ i> 两次密码输入不一致';
}
}
}
register.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 注册页面</ title>
< link rel = " stylesheet" href = " css/base.css" >
< link rel = " stylesheet" href = " css/register.css" >
< script src = " js/reg.js" > </ script>
</ head>
< body>
< div class = " w" >
< div class = " header" >
< div class = " logo" >
< a href = " index.html" >
< img src = " img/logo.png" alt = " " >
</ a>
</ div>
</ div>
< div class = " registerarea" >
< h3>
注册新用户
< em>
我有账号,去< a href = " login.html" > 登陆</ a>
</ em>
</ h3>
< div class = " reg_form" >
< form action = " demo.php" >
< ul>
< li>
< label for = " tel" > 手机号:</ label>
< input type = " text" class = " inp" id = " tel" >
< span class = " " >
</ span>
</ li>
< li>
< label for = " " > QQ:</ label>
< input type = " text" class = " inp" id = " qq" >
< span> </ span>
</ li>
< li>
< label for = " " > 昵称:</ label>
< input type = " text" class = " inp" id = " nc" >
< span> </ span>
</ li>
< li>
< label for = " " > 短信验证码:</ label>
< input type = " text" class = " inp" id = " msg" >
< span> </ span>
</ li>
< li>
< label for = " " > 登陆密码:</ label>
< input type = " text" class = " inp" id = " pwd" >
< span>
</ span>
</ li>
< li class = " safe" >
安全程度
< em class = " ruo" > 弱</ em>
< em class = " zhong" > 中</ em>
< em class = " qiang" > 强</ em>
</ li>
< li>
< label for = " " > 确认密码:</ label>
< input type = " text" class = " inp" id = " surepwd" >
< span> </ span>
</ li>
< li class = " agree" >
< input type = " checkbox" > 同意协议并注册
< a href = " #" > 《知果果用户协议》</ a>
</ li>
< li>
< input type = " submit" value = " 完成注册" class = " over" >
</ li>
</ ul>
</ form>
</ div>
</ div>
< div class = " footer" >
< p class = " links" >
关于我们 | 联系我们 | 联系客服 | 商家入驻 | 营销中心 | 手机品优购 | 友情链接 | 销售联盟 | 品优购社区 | 品优购公益 | English Site | Contact U
</ p>
< p class = " copyright" >
地址:北京市昌平区建材城西路金燕龙办公楼一层 邮编:100096 电话:400-618-4000 传真:010-82935100 邮箱: zhanghj+itcast.cn < br> 京ICP备08001421号京公网安备110108007702
</ p>
</ div>
</ div>
</ body>
</ html>
3.1.2.6 替换
stringObject.replace(regexp/substr,replacement)
1 第一个参数: 被替换的字符串 或者 正则表达式
2 第二个参数: 替换为的字符串
3 返回值是一个替换完毕的新字符串
正则表达式参数
switch(也称为修饰符) 按照什么样的模式来匹配. 有三种值:
g:全局匹配
i:忽略大小写
gi:全局匹配 + 忽略大小写
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> Document</ title>
< style>
textarea {
width : 300px;
height : 100px;
border : 1px solid #ccc;
}
</ style>
</ head>
< body>
< textarea name = " " id = " message" > </ textarea> < button> 提交</ button>
< div> </ div>
< script>
var text = document. querySelector ( 'textarea' ) ;
var btn = document. querySelector ( 'button' ) ;
var div = document. querySelector ( 'div' ) ;
btn. onclick = function ( ) {
div. innerHTML = text. value. replace ( /激情|gay/g , '**' ) ;
}
</ script>
</ body>
</ html>
4.1 ES6
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
4.1.1 使用let关键字声明变量
使用let关键字声明的变量才具有块级作用域,不存在变量提升,暂时性死区,使用var声明的变量不具备块级作用域特性.
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 使用let关键字声明变量</ title>
</ head>
< body>
< script type = " text/javascript" >
var num = 10
if ( true ) {
console. log ( num) ;
let num = 20 ;
}
</ script>
</ body>
</ html>
经典面试题
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 经典面试题</ title>
</ head>
< body>
< script type = " text/javascript" >
let arr = [ ] ;
for ( let i = 0 ; i < 2 ; i++ ) {
arr[ i] = function ( ) {
console. log ( i) ;
}
}
arr[ 0 ] ( ) ; 0
arr[ 1 ] ( ) ; 1
</ script>
</ body>
</ html>
4.1.2 使用const关键字声明常量
具有块级作用域
声明常量时必须赋值
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 使用const关键字声明常量</ title>
</ head>
< body>
< script type = " text/javascript" >
const PI = 3.14 ;
const ary = [ 100 , 200 ] ;
ary[ 0 ] = 123 ;
ary = [ 1 , 2 ]
console. log ( ary) ;
</ script>
</ body>
</ html>
4.1.3 let、const、var 的区别
1. 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。
2. 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
3. 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
4.1.4 解构赋值
按照一定模式,从数组中或对象中提取值,将提取出来的值赋值给另外的变量。
4.1.4.1 数组解构
ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也可以实现解构。
如果解构不成功,变量的值为undefined。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 数组解构</ title>
</ head>
< body>
< script type = " text/javascript" >
let ary = [ 1 , 2 , 3 ] ;
let [ a, b, c, d, e] = ary;
console. log ( a)
console. log ( b)
console. log ( c)
console. log ( d)
console. log ( e)
</ script>
</ body>
</ html>
4.1.4.2 对象解构
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 对象解构</ title>
</ head>
< body>
< script type = " text/javascript" >
let person = {
name: 'lisi' , age: 30 , sex: '男' } ;
let {
name: myName} = person;
console. log ( myName)
</ script>
</ body>
</ html>
4.1.5 箭头函数
函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
如果形参只有一个,可以省略小括号
箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 箭头函数</ title>
</ head>
< body>
< script type = " text/javascript" >
function fn ( ) {
console. log ( this ) ;
return ( ) => {
console. log ( this )
}
}
const obj = {
name: 'zhangsan' } ;
const resFn = fn. call ( obj) ;
resFn ( ) ;
</ script>
</ body>
</ html>
箭头函数面试题
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 箭头函数面试题</ title>
</ head>
< body>
< script type = " text/javascript" >
var age = 100 ;
var obj = {
age: 20 ,
say: ( ) => {
alert ( this . age)
}
}
}
obj. say ( ) ;
</ script>
</ body>
</ html>
4.1.6 剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 剩余参数</ title>
</ head>
< body>
< script type = " text/javascript" >
let ary1 = [ '张三' , '李四' , '王五' ] ;
let [ s1, ... s2] = ary1;
console. log ( s1)
console. log ( s2)
</ script>
</ body>
</ html>
4.1.7 扩展运算符
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。
扩展运算符可以应用于合并数组。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 扩展运算符</ title>
</ head>
< body>
< div> 1</ div>
< div> 4</ div>
< div> 3</ div>
< div> 6</ div>
< div> 2</ div>
< div> 5</ div>
< script type = " text/javascript" >
var oDivs = document. getElementsByTagName ( 'div' ) ;
console. log ( oDivs)
var ary = [ ... oDivs] ;
ary. push ( 'a' ) ;
console. log ( ary) ;
</ script>
</ body>
</ html>
4.1.8 Array
4.1.8.1 Array.from方法
伪数组或可遍历对象转换为真正的数组
let oDivs = document.getElementsByTagName('div');
oDivs = [...oDivs];
Array.from()
将类数组或可遍历对象转换为真正的数组
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
let arrayLike = {
"0": 1,
"1": 2,
"length": 2
}
let newAry = Array.from(aryLike, item => item *2)
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Array.from方法</ title>
</ head>
< body>
< script type = " text/javascript" >
var arrayLike = {
"0" : "1" ,
"1" : "2" ,
"length" : 2
}
var ary = Array. from ( arrayLike, item => item * 2 )
console. log ( ary)
</ script>
</ body>
</ html>
4.1.8.2 Array.find方法介绍
用于找出第一个符合条件的数组成员,如果没有找到返回undefined
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> find方法</ title>
</ head>
< body>
< script type = " text/javascript" >
var ary = [ {
id: 1 ,
name: '张三'
} , {
id: 2 ,
name: '李四'
} ] ;
let target = ary. find ( item => item. id == 3 ) ;
console. log ( target)
</ script>
</ body>
</ html>
4.1.8.3 Array.findIndex方法
用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> findIndex方法</ title>
</ head>
< body>
< script type = " text/javascript" >
let ary = [ 10 , 20 , 50 ] ;
let index = ary. findIndex ( item => item > 15 ) ;
console. log ( index)
</ script>
</ body>
</ html>
4.1.8.4 Array.includes方法介绍
表示某个数组是否包含给定的值,返回布尔值。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> includes方法</ title>
</ head>
< body>
< script type = " text/javascript" >
let ary = [ "a" , "b" , "c" ] ;
let result = ary. includes ( 'a' )
console. log ( result)
result = ary. includes ( 'e' )
console. log ( result)
</ script>
</ body>
</ html>
4.1.9 模板字符串
ES6新增的创建字符串的方式,使用反引号定义。
模板字符串中可以解析变量。
模板字符串中可以换行
在模板字符串中可以调用函数。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 模板字符串</ title>
</ head>
< body>
< script type = " text/javascript" >
const fn = ( ) => {
return '我是fn函数'
}
let html = `我是模板字符串 ${
fn ( ) } ` ;
console. log ( html)
</ script>
</ body>
</ html>
4.1.10 startsWith方法和endsWith方法
startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> startsWith方法和endsWith方法</ title>
</ head>
< body>
< script type = " text/javascript" >
let str = 'Hello ECMAScript 2015' ;
let r1 = str. startsWith ( 'Hello' ) ;
console. log ( r1) ;
let r2 = str. endsWith ( '2016' ) ;
console. log ( r2)
</ script>
</ body>
</ html>
4.1.11 repeat方法介绍
repeat方法表示将原字符串重复n次,返回一个新字符串。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> repeat方法</ title>
</ head>
< body>
< script type = " text/javascript" >
console. log ( "y" . repeat ( 5 ) )
</ script>
</ body>
</ html>
4.1.12 Set
Set本身是一个构造函数,用来生成 Set 数据结构。
Set函数可以接受一个数组作为参数,用来初始化。
add(value):添加某个值,返回 Set 结构本身
delete(value):删除某个值,返回一个布尔值,表示删除是否成功
has(value):返回一个布尔值,表示该值是否为 Set 的成员
clear():清除所有成员,没有返回值
Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Set</ title>
</ head>
< body>
< script type = " text/javascript" >
const s5 = new Set ( [ 'a' , 'b' , 'c' ] ) ;
s5. forEach ( value => {
console. log ( value)
} )
</ script>
</ body>
</ html>