获得徽章 0
- 深浅拷贝:
1. 首先浅拷贝和深拷贝只针对想Object,Array这样的复杂对象,简单来说,浅拷贝只复制一层对象的属性,二深拷贝则复制了所有的层级。
2. 对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会 改变,而深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: '小pink'
}
}
// 把对象转换为 JSON 字符串
// console.log(JSON.stringify(obj))
const o = JSON.parse(JSON.stringify(obj))
console.log(o)
o.family.baby = '123'
console.log(obj)
异常处理:
了解 JavaScript 中程序异常处理的方法,提升代码运行的健壮性
throw异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行
function counter(x, y) {
if(!x || !y) {
// throw '参数不能为空!';
throw new Error('参数不能为空!')
}
return x + y
}
counter()
1. throw` 抛出异常信息,程序也会终止执行
2. `throw` 后面跟的是错误提示信息
3. `Error` 对象配合 `throw` 使用,能够设置更详细的错误信息展开赞过评论2 - 原型链:
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链
// Person 构造函数
function Person() {
this.arms = 2;
this.walk = function () {}
}
// Person 原型对象
Person.prototype.legs = 2;
Person.prototype.eyes = 2;
Person.prototype.sing = function () {}
Person.prototype.sleep = function () {}
// Chinese 构造函数
function Chinese() {
this.skin = 'yellow';
this.language = '中文';
}
// Chinese 原型对象
Chinese.prototype = new Person();
Chinese.prototype.constructor = Chinese;
// 实例化
let c1 = new Chinese();
console.log(c1)
在 JavaScript 对象中包括了一个非标准备的属性 `__proto__` 它指向了构造函数的原型对象,通过它可以清楚的查看原型对象的链状结构。展开赞过评论2 - 原型继承:
基于构造函数原型对象实现面向对象的继承特性
// 所有人
function Person() {
// 人的特征
this.arms = 2;
this.legs = 2;
this.eyes = 2;
// 人的行为
this.walk = function () {}
this.sing = function () {}
this.sleep = function () {}
}
// 中国人
function Chinese() {
this.skin = 'yellow';
this.language = '中文';
}
// 日本人
function Japanese() {
this.skin = 'yellow';
this.language = '日文';
}
上述代码可以理解成将 `Chinese` 和 `Japanese` 共有的属性和方法提取出来了,也就是说 `Chinese` 和 `Japanese` 需要【共享】一些属性和方法,而原型对象的属性和方法恰好是可以被用来共享的
// 中国人
function Chinese() {
this.skin = 'yellow';
this.language = '中文';
}
// 日本人
function Japanese() {
this.skin = 'yellow';
this.language = '日文';
}
// 人们【共有】的行为特征
let people = {
// 人的特征
arms: 2,
legs: 2,
eyes:2,
// 人的行为
walk: function () {},
sleep: function () {},
sing: function () {}
}
// 为 prototype 重新赋值
Chinese.prototype = people;
Chinese.prototype.constructor = Chinese;展开赞过评论2 - 继承:继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义,分别封装中国人和日本人的行为特征来理解编程中继承的含义,代码如下:
// 封装中国人的行为特征
function Chinese() {
// 中国人的特征
this.arms = 2;
this.legs = 2;
this.eyes = 2;
this.skin = 'yellow';
this.language = '中文';
// 中国人的行为
this.walk = function () {}
this.sing = function () {}
this.sleep = function () {}
}
// 封装日本人的行为特征
function Japanese() {
// 日本人的特征
this.arms = 2;
this.legs = 2;
this.eyes = 2;
this.skin = 'yellow';
this.language = '日文';
// 日本人的行为
this.walk = function () {}
this.sing = function () {}
this.sleep = function () {}
}
其实我们都知道无论是中国人、日本人还是其它民族,人们的大部分特征是一致的,然而体现在代码中时人的相同的行为特征被重复编写了多次,代码显得十分冗余,我们可以将重复的代码抽离出来展开赞过评论2 - 原型对象:
实际上每一个构造函数都有一个名为 `prototype` 的属性,译成中文是原型的意思,`prototype` 的是对象类据类型,称为构造函数的原型对象,每个原型对象都具有 `constructor` 属性代表了该原型对象对应的构造函数
function Person() {
}
// 每个函数都有 prototype 属性
console.log(Person.prototype)
了解了 JavaScript 中构造函数与原型对象的关系后,再来看原型对象具体的作用,如下代码所示
function Person() {
// 此处未定义任何方法
}
// 为构造函数的原型对象添加方法
Person.prototype.sayHi = function () {
console.log('Hi~');
}
// 实例化
let p1 = new Person();
p1.sayHi(); // 输出结果为 Hi~
构造函数 `Person` 中未定义任何方法,这时实例对象调用了原型对象中的方法 `sayHi`,接下来改动一下代码:
function Person() {
// 此处定义同名方法 sayHi
this.sayHi = function () {
console.log('嗨!');
}
}
// 为构造函数的原型对象添加方法
Person.prototype.sayHi = function () {
console.log('Hi~');
}
let p1 = new Person();
p1.sayHi(); // 输出结果为 嗨!展开赞过评论2 - 面向对象:
面向对象编程是一种程序设计思想,它具有 3 个显著的特征:封装、继承、多态。
封装:
封装的本质是将具有关联的代码组合在一起,其优势是能够保证代码复用且易于维护,函数是最典型也是最基础的代码封装形式,面向对象思想中的封装仍以函数为基础,但提供了更高级的封装形式
命名空间:
// 普通对象(命名空间)形式的封装
let beats = {
name: '狼',
setName: function (name) {
this.name = this.name;
},
getName() {
console.log(this.name);
}
}
beats.setName('熊');
beats.getName();
以往以普通对象(命名空间)形式封装的代码只是单纯把一系列的变量或函数组合到一起,所有的数据变量都被用来共享(使用 this 访问)
function Person() {
this.name = '佚名';
// 设置名字
this.setName = function (name) {
this.name = name;
}
// 读取名字
this.getName = () => {
console.log(this.name);
}
}
// 实例对像,获得了构造函数中封装的所有逻辑
let p1 = new Person();
p1.setName('小明');
console.log(p1.name);
// 实例对象
let p2 = new Person();
console.log(p2.name);
同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的。
1. 构造函数体现了面向对象的封装特性
2. 构造函数实例创建的对象彼此独立、互不影响
3. 命名空间式的封装无法保证数据的独立性展开赞过12 - 1. 实例属性 `length` 用来获取字符串的度长(重点)
2. 实例方法 `split('分隔符')` 用来将字符串拆分成数组(重点)
3. 实例方法 `substring(需要截取的第一个字符的索引[,结束的索引号])` 用于字符串截取(重点)
4. 实例方法 `startsWith(检测字符串[, 检测位置索引号])` 检测是否以某字符开头(重点)
5. 实例方法 `includes(搜索的字符串[, 检测位置索引号])` 判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false(重点)
6. 实例方法 `toUpperCase` 用于将字母转换成大写
7. 实例方法 `toLowerCase` 用于将就转换成小写
8. 实例方法 `indexOf` 检测是否包含某字符
9. 实例方法 `endsWith` 检测是否以某字符结尾
10. 实例方法 `replace` 用于替换字符串,支持正则匹配
11. 实例方法 `match` 用于查找字符串,支持正则匹配
String 也可以当做普通函数使用,这时它的作用是强制转换成字符串数据类型。
Number` 是内置的构造函数,用于创建数值
// 使用构造函数创建数值
let x = new Number('10')
let y = new Number(5)
// 字面量创建数值
let z = 20
1. 推荐使用字面量方式声明数值,而不是 `Number` 构造函数
2. 实例方法 `toFixed` 用于设置保留小数位的长度展开赞过评论2 - 包装类型:
在 JavaScript 中的字符串、数值、布尔具有对象的使用特征,如具有属性和方法,如下代码举例
// 字符串类型
const str = 'hello world!'
// 统计字符的长度(字符数量)
console.log(str.length)
// 数值类型
const price = 12.345
// 保留两位小数
price.toFixed(2) // 12.34
之所以具有对象特征的原因是字符串、数值、布尔类型数据是 JavaScript 底层使用 Object 构造函数“包装”来的,被称为包装类型。
String` 是内置的构造函数,用于创建字符串
// 使用构造函数创建字符串
let str = new String('hello world!');
// 字面量创建字符串
let str2 = '你好,世界!';
// 检测是否属于同一个构造函数
console.log(str.constructor === str2.constructor); // true
console.log(str instanceof String); // false展开赞过评论2 - 1. 推荐使用字面量方式声明数组,而不是 `Array` 构造函数
2. 实例方法 `forEach` 用于遍历数组,替代 `for` 循环 (重点)
3. 实例方法 `filter` 过滤数组单元值,生成新数组(重点)
4. 实例方法 `map` 迭代原数组,生成新数组(重点)
5. 实例方法 `join` 数组元素拼接为字符串,返回字符串(重点)
6. 实例方法 `find` 查找元素, 返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined(重点)
7. 实例方法`every` 检测数组所有元素是否都符合指定条件,如果**所有元素**都通过检测返回 true,否则返回 false(重点)
8. 实例方法`some` 检测数组中的元素是否满足指定条件 **如果数组中有**元素满足条件返回 true,否则返回 false
9. 实例方法 `concat` 合并两个数组,返回生成新数组
10. 实例方法 `sort` 对原数组单元值排序
11. 实例方法 `splice` 删除或替换原数组单元
12. 实例方法 `reverse` 反转数组
13. 实例方法 `findIndex` 查找元素的索引值展开赞过评论2 - 引用类型:
Object` 是内置的构造函数,用于创建普通对象
// 通过构造函数创建普通对象
const user = new Object({name: '小明', age: 15})
// 这种方式声明的变量称为【字面量】
let student = {name: '杜子腾', age: 21}
// 对象语法简写
let name = '小红';
let people = {
// 相当于 name: name
name,
// 相当于 walk: function () {}
walk () {
console.log('人都要走路...');
}
}
console.log(student.constructor);
console.log(user.constructor);
console.log(student instanceof Object);
1. 推荐使用字面量方式声明对象,而不是 `Object` 构造函数
2. `Object.assign` 静态方法创建新的对象
3. `Object.keys` 静态方法获取对象中所有属性
4. `Object.values` 表态方法获取对象中所有属性值
Array` 是内置的构造函数,用于创建数组
// 构造函数创建数组
let arr = new Array(5, 7, 8);
// 字面量方式创建数组
let list = ['html', 'css', 'javascript']
数组赋值后,无论修改哪个变量另一个对象的数据值也会相当发生改变。展开赞过评论2