目录
13.3.2 startsWith方法和endsWith方法
1.学习视频
2019全新javaScript进阶面向对象ES6_哔哩哔哩_bilibili
2.面向过程与面向对象
面向过程:按照过程来解决问题(性能好,但不易于维护)
面向对象:先找出对象,每个对象有各自的功能,再来解决问题(用于多人合作,易于维护,但性能没有面向过程好)
3.ES6中的类和对象
3.1类和对象的定义
3.2 创建类和生成实例
// 1. 创建类 class 创建一个 明星类
class Star {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
}
// 2. 利用类创建对象 new
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 20);
console.log(ldh);
console.log(zxy);
//(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
//(2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
//(3) constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
//(4) 生成实例 new 不能省略
//(5) 最后注意语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function
3.3类中添加方法
class Star {
// 类的共有属性放到 constructor 里面
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing(song) {
// console.log('我唱歌');
console.log(this.uname + song);
}
}
注意:多个函数方法之间不用逗号分隔。
3.4 类的继承
super关键字:调用父类的构造函数(super(参数))或普通函数(super.方法名())
注意:在子类的constructor函数中, super必须在this之前调用
// super 关键字调用父类普通函数
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
say() {
console.log(super.say() + '的儿子');
// super.say() 就是调用父类中的普通函数 say()
}
}
var son = new Son();
son.say();
// 父类有加法方法
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 调用父类的构造函数
// super 必须在子类this之前调用
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();
继承中的属性或方法查找原则:就近原则(先找子类再找父类)
3.5 类的注意事项
1.ES6没有变量提升,必须先定义类再实例化对象。
2.类中的共有属性和方法一定要加this使用
3.constructor里的this指向实例对象,方法里的this指向方法调用者
4.
sing后不能加(),不然,不用点击就直接执行sing()方法
5.如何把方法里的this变为实例对象:
方法一:
1.在class外:var that;
2.constructor里: that = this;
3.方法里: 把this换成that
方法二:
1.this还是指向调用者,但增加了this参数。
2.方法中接收传递的this。
3.6 面向对象案例的知识点
1.创建元素并追加到父元素中
一、普通做法:先creatElement()再innerHTML,最后appendChild(),例子如下:
var tr = document.createElement('tr');
tr.innerHTML = '<td>1</td><td>1</td><td>1</td>';
tbody.appendChild(tr);
二、高级做法:利用element.insertAdjacentHTML(position, text)可以直接把字符串格式元素添加到父元素中
position(位置):
'beforebegin'——元素自身的前面
'afterbegin'——插入元素内部的第一个子节点之前
'beforeend'——插入元素内部的最后一个子节点之后
'afterend'——元素自身的后面
例子:
// (1) 创建li元素
var li = '<li class="liactive"><span>新选项卡</span><span class="iconfont icon-guanbi"></span></li>';
// (2) 把元素追加到对应的父元素里面
that.ul.insertAdjacentHTML('beforeend', li);
3.7 双击编辑
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();
}
}
}
4.构造函数和原型
4.1 概述
1.ES6之前,JS中没有引入类的概念,用构造函数来定义对象和它们的特征。目前浏览器的JavaScript是ES5版本,大多数高版本的浏览器也支持ES6,不过实现了ES6的部分特性和功能。
创建对象的三种方法:
// 1. 利用 new Object() 创建对象
var obj1 = new Object();
// 2. 利用 对象字面量创建对象
var obj2 = {};
// 3. 利用构造函数创建对象
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();
4.2 实例成员和静态成员
实例成员:构造函数内部通过this添加的成员,按上例则uname age sing就为实例成员;且实例成员只能通过实例化的对象来访问,如:ldh.sing()
静态成员:构造函数本身添加的成员,如在构造函数外,编写Star.sex='男',则sex为静态成员;且静态成员只能通过构造函数来访问,如:console.log(Star.sex);
4.3 原型
前提:原来定义的构造函数,实例化对象中相同的方法都有不同的地址,都给每个实例化对象的公共方法分配内存,所以存在浪费内存的问题。
原型:prototype为原型对象,有共享方法的作用。
用法:Star.prototype.sing = function() {
console.log('我会唱歌');
}
注意:一般情况下,公共属性定义到构造函数中,公共的方法我们放到原型对象上。
4.4 对象原型 --proto--
1.每个对象都有属性--proto--指向构造函数prototype原型对象,所以可以使用构造函数prototype的属性和方法。
2.方法查找规则:先在实例对象上找是否有方法,没有再去prototype身上找方法。
3.--proto--是一个非标准属性,实际开发中,不可以使用这个属性。
4.5 constructor 构造函数
对象原型(--proto--)和构造函数原型对象(prototype)都有一个属性constructor属性,constructor称为构造函数,它指回构造函数本身。
作用:让原型对象重新指向原来的构造函数。
使用场景:以原型对象赋值一个对象的形式修改了原来的原型对象,就必修利用constructor指回原来的构造函数。例子如下:
Star.prototype = {
// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
constructor: Star,
sing: function() {
console.log('我会唱歌');
},
movie: function() {
console.log('我会演电影');
}
}
4.6 构造函数、实例、原型对象三者之间的关系
4.7原型链
只要是对象就有__proto__原型,指向原型对象。
JavaScript的成员查找机制:在原型链上查找
执行:就近原则
4.8 原型对象中this的指向
构造函数和原型对象里的this,都指向实例对象
4.9扩展内置对象方法
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
};
//下面的方法不可行
// Array.prototype = {
// sum: function() {
// var sum = 0;
// for (var i = 0; i < this.length; i++) {
// sum += this[i];
// }
// return sum;
// }
// }
5.继承
ES6之前没有提供extends继承,我们通过构造函数+原型对象模拟实现继承,称为组合继承。
5.1 call()
1.调用函数:fun.call()
2.修改函数运行时的this指向:fun.call(thisArg, arg1, arg2, …)
thisArg: 当前调用函数this的指向对象
arg1,arg2:传递的其他参数
5.2 利用父构造函数继承属性
//父构造函数
function Father(uname, age){
//this 指向父亲构造函数的对象实例
this.uname = uname;
this.age = age;
}
//子构造函数
function Son(uname, age, score){
// this 指向儿子构造函数的对象实例
Father.call(this, uname, age); //把父构造函数的this换成Son
this.score = score;
}
var son = new Son(