-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
420 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# new操作符 | ||
|
||
new操作符会进行四步: | ||
1. 创建一个空对象 | ||
2. 把空对象和构造函数的prototype关联起来 | ||
3. 把构造函数的this绑定到空对象上 | ||
4. 根据构造函数的返回值类型返回结果,如果是值类型就返回空对象,如果是引用类型就返回引用类型 | ||
|
||
```JavaScript | ||
function newFn(Fun, ...args) { | ||
// 1. 创建一个空对象 | ||
let obj = {}; | ||
// 2. 把空对象和构造函数的prototype关联起来 | ||
obj.__proto__ = Fun.prototype; | ||
// 3. 把构造函数的this绑定到空对象上 | ||
const result = Fun.apply(obj,args) | ||
// 4. 根据构造函数的返回值类型返回结果,如果是值类型就返回空对象,如果是引用类型就返回引用类型 | ||
return result instanceof Object ? result : obj; | ||
} | ||
|
||
function person(name) { | ||
this.name = name; | ||
} | ||
|
||
person.prototype.say = () => { | ||
console.log('说话'); | ||
}; | ||
|
||
let obj = newFn(person, "Rarrot"); | ||
obj.say(); // 说话 | ||
console.log(obj) // person {name: 'Rarrot'} | ||
``` | ||
|
||
## 注意 | ||
|
||
1. 引用类型之间通过new操作符创建的对象是不相等的,例如: | ||
|
||
```JavaScript | ||
function Person() { | ||
this.name = 'Rarrot'; | ||
} | ||
|
||
let person1 = new Person(); | ||
let person2 = new Person(); | ||
|
||
console.log(person1 === person2); // false | ||
console.log([ 1 ] === [ 1 ]); // false | ||
``` | ||
|
||
2. 对象的key都是**字符串**,如果是引用类型也会自动转换为字符串,例如: | ||
|
||
```JavaScript | ||
let obj = {}; | ||
let arr1 = { a: 1 }; | ||
let arr2 = { b: 2 }; | ||
obj[arr1] = 1; | ||
obj[arr2] = 2;// arr1.toString() === arr2.toString(),所以会覆盖掉arr1 | ||
for (let key in obj) { | ||
console.log(key + ':' + obj[key]); // [object Object]:2 | ||
} | ||
``` | ||
|
||
3. 对象找属性|方法的顺序: | ||
|
||
在对象本身找 ==> 在构造函数上找 ==> 在对象原型上找 ==> 构造函数原型上找 ==> 对象上一级找 ==> Object.prototype找 | ||
|
||
```JavaScript | ||
function Person() { | ||
this.name = 'Rarrot'; | ||
this.age = 777; // 在构造函数中添加 | ||
} | ||
Person.prototype.age = '999'; // 在构造函数原型上添加 | ||
let person = new Person(); | ||
person.age = '666'; // 在对象本身添加 | ||
person.__proto__.age = '888'; // 在对象原型上添加 | ||
Object.prototype.age = '000'; // 在Object上添加 | ||
console.log(person.age); // 666 | ||
console.log(person.__proto__ === Person.prototype); // true | ||
console.log(Person.prototype.__proto__ === Object.prototype); // true | ||
console.log(Object.prototype.__proto__); // null | ||
``` | ||
|
||
## object | ||
|
||
为什么在Object 参考页,会发现左侧列出许多属性和方法——大大超过我们在自己定义的对象中看到的继承成员的数量。 | ||
|
||
原因在于,继承的属性和方法是定义在 prototype 属性之上的(你可以称之为子命名空间 (sub namespace) )——那些以 Object.prototype. 开头的属性,而非仅仅以 Object. 开头的属性。 | ||
|
||
prototype 属性的值是一个对象,我们希望被原型链下游的对象继承的属性和方法,都被储存在其中,而不希望被继承的则放于Object自身,记住每一个对象都有一个原型(prototype)属性,其指向另一个对象。由下图可以看出,prototype内部存在有许多的属性和方法,原因即为以上所述 | ||
|
||
![](https://cdn.jsdelivr.net/gh/hr1201/img@main/imgs/202402291750719.png) | ||
|
||
于是 Object.prototype.watch()、[Object.prototype.valueOf()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf) 等等成员,适用于任何继承自 Object() 的对象类型,包括使用构造器创建的新的对象实例。 | ||
|
||
[Object.is()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/is)、[Object.keys()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys),以及其他不在 prototype 对象内的成员,不会被“对象实例”或“继承自 Object() 的对象类型”所继承。这些方法/属性仅能被 Object() 构造器自身使用。 |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# 作用域 | ||
|
||
1. **全局作用域**:全局作用域是最外围的作用域,根据 ECMAScript 的定义,全局作用域在网页中任何地方都能访问到。 | ||
|
||
2. **函数作用域**:函数作用域是在函数内部声明的变量只能在函数内部访问。 | ||
|
||
3. **块级作用域**:块级作用域是在代码块内部声明的变量只能在该代码块内部访问。 | ||
|
||
|
||
## 全局作用域 | ||
|
||
全局作用域是最外围的作用域,根据 ECMAScript 的定义,全局作用域在网页中任何地方都能访问到。 | ||
|
||
```javascript | ||
var a = 1; | ||
console.log(a); // 1 | ||
``` | ||
|
||
## 函数作用域 | ||
|
||
函数作用域是在函数内部声明的变量只能在函数内部访问。 | ||
|
||
```javascript | ||
function foo() { | ||
var a = 1; | ||
console.log(a); // 1 | ||
} | ||
|
||
foo(); | ||
console.log(a); // Uncaught ReferenceError: a is not defined | ||
``` | ||
|
||
## 块级作用域 | ||
|
||
块级作用域是在代码块内部声明的变量只能在该代码块内部访问。 | ||
|
||
```javascript | ||
console.log(a); // undefined,变量提升 | ||
|
||
if (true) { | ||
var a = 1; | ||
console.log(a); // 1 | ||
|
||
let b = 2; | ||
console.log(b); // 2 | ||
} | ||
|
||
console.log(a); // 1 | ||
console.log(b); // Uncaught ReferenceError: b is not defined | ||
``` | ||
|
||
## 作用域链 | ||
|
||
作用域链是一个指向变量对象的指针列表,它保证了变量的有序访问。内部可以访问外部的变量,但是外部不能访问内部的变量。 | ||
|
||
注意:如果内部变量和外部变量同名,内部变量会覆盖外部变量。 | ||
|
||
```javascript | ||
var a = 1; | ||
|
||
function foo() { | ||
var b = 2; | ||
|
||
function bar() { | ||
var c = 3; | ||
console.log(a); // 1 | ||
console.log(b); // 2 | ||
console.log(c); // 3 | ||
} | ||
|
||
bar(); | ||
} | ||
|
||
foo(); | ||
``` | ||
|
||
## 优先级 | ||
|
||
声明变量 > 声明普通函数 > 参数 > 变量提升 | ||
|
||
```javascript | ||
function foo() { | ||
// var a = 1; // 声明a变量 | ||
|
||
console.log(a); // ƒ a() {},如果前面有声明a变量,则输出声明变量的值 | ||
|
||
var a = 2; // 变量提升 | ||
|
||
// 普通声明函数是不看写函数时的位置的,只看函数声明的位置 | ||
function a() {} | ||
} | ||
|
||
foo(); | ||
``` | ||
|
||
## 注意 | ||
|
||
注意声明变量时不使用`var`关键字,会自动提升到全局作用域。 | ||
|
||
```javascript | ||
(function () { | ||
var a = b = 10; | ||
|
||
/* | ||
* 等价于 | ||
* b = 10; // 全局作用域 | ||
* var a = b; | ||
*/ | ||
})() | ||
|
||
console.log(b); // 10 | ||
|
||
console.log(a); // Uncaught ReferenceError: a is not defined | ||
``` | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# 数组 | ||
|
||
## 判断数组 | ||
|
||
```js | ||
// 1. isArray | ||
const arr = [1, 2, 3] | ||
console.log(Array.isArray(arr)) // true | ||
|
||
// 2. instanceof | ||
console.log(arr instanceof Array) // true | ||
|
||
// 3. constructor | ||
console.log(arr.constructor === Array) // true | ||
|
||
// 4. Object.prototype.toString.call() | ||
console.log(Object.prototype.toString.call(arr).indexOf('Array') !== -1) // true | ||
|
||
// 5. Array.prototype.isPrototypeOf() | ||
console.log(Array.prototype.isPrototypeOf(arr)) // true | ||
``` | ||
|
||
## slice和splice | ||
|
||
`slice`和`splice`都是数组的方法,但是它们的作用不同。 | ||
|
||
- `slice`:返回一个新的数组,包含从开始到结束(不包括结束)的元素,原数组不会被修改。 | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5] | ||
const newArr = arr.slice(1, 3) | ||
console.log(newArr) // [2, 3] | ||
console.log(arr) // [1, 2, 3, 4, 5] | ||
``` | ||
|
||
- `splice`:从数组中添加或删除元素,返回被删除的元素,原数组会被修改。 | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5] | ||
const newArr = arr.splice(1, 3) | ||
console.log(newArr) // [2, 3, 4] | ||
console.log(arr) // [1, 5] | ||
``` | ||
|
||
## 数组去重 | ||
|
||
### 1. Set | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5, 1, 2, 3] | ||
const newArr = [...new Set(arr)] | ||
console.log(newArr) // [1, 2, 3, 4, 5] | ||
``` | ||
|
||
### 2. filter | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5, 1, 2, 3] | ||
const newArr = arr.filter((item, index) => arr.indexOf(item) === index) | ||
console.log(newArr) // [1, 2, 3, 4, 5] | ||
``` | ||
|
||
### 3. reduce | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5, 1, 2, 3] | ||
const newArr = arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []) | ||
console.log(newArr) // [1, 2, 3, 4, 5] | ||
``` | ||
|
||
## 数组扁平化 | ||
|
||
### 1. flat | ||
|
||
```js | ||
const arr = [1, [2, 3], [4, [5, 6]]] | ||
const newArr = arr.flat(Infinity) | ||
console.log(newArr) // [1, 2, 3, 4, 5, 6] | ||
``` | ||
|
||
### 2. reduce | ||
|
||
```js | ||
const arr = [1, [2, 3], [4, [5, 6]]] | ||
const flatten = arr => arr.reduce((prev, cur) => prev.concat(Array.isArray(cur) ? flatten(cur) : cur), []) | ||
const newArr = flatten(arr) | ||
console.log(newArr) // [1, 2, 3, 4, 5, 6] | ||
``` | ||
|
||
## 数组乱序 | ||
|
||
```js | ||
const arr = [1, 2, 3, 4, 5] | ||
const newArr = arr.sort(() => Math.random() - 0.5) | ||
console.log(newArr) | ||
``` | ||
|
||
|
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.