- 對象原型
https://zhuanlan.zhihu.com/p/107847864
https://doc.houdunren.com/js/11%20原型與繼承.html#原型對象
image.png
原型中保存引用類型會造成對象共享屬性,所以一般只會在原型中定義方法
function User() {}
User.prototype = {
lessons: ["JS", "VUE"]
};
const lisi = new User();
const wangwu = new User();
lisi.lessons.push("CSS");
console.log(lisi.lessons); //["JS", "VUE", "CSS"]
console.log(wangwu.lessons); //["JS", "VUE", "CSS"]
- 變量提升 只有var存在變量提升
https://doc.houdunren.com/js/1%20基礎知識.html#變量提升 - TDZ 又稱暫時性死區 let/const存在暫時性死區
https://doc.houdunren.com/js/1%20基礎知識.html#tdz - var/let/const
const: 申明引用類型對象或者數組是可以修改的
https://doc.houdunren.com/js/1%20基礎知識.html#塊作用域
https://blog.csdn.net/weixin_40784198/article/details/81989962
https://doc.houdunren.com/js/9%20作用域與閉包.html#let-const - Object.freeze 凍結變量
https://doc.houdunren.com/js/1%20基礎知識.html#object-freeze - undefined/null
undefined:未賦值與未定義的變量值都為 undefined
null: 用于定義一個空對象,即如果變量要用來保存引用類型,
可以在初始化時將其設置為null
- 標簽(label) 為程序定義位置,可以使用continue/break跳到該位置
continue hdcms: 跳出n的循環
break houdunren: 跳出I的循環
houdunren: for (let i = 1; i <= 10; i++) {
hdcms: for (let n = 1; n <= 10; n++) {
if (n % 2 != 0) {
continue hdcms;
}
console.log(i, n);
if (i + n > 15) {
break houdunren;
}
}
}
- for/in 用于遍歷對象的所有屬性,for/in主要用于
遍歷對象
,不建議用來遍歷數組 - for/of 用來遍歷
Arrays(數組), Strings(字符串), Maps(映射), Sets(集合)
等可迭代的數據結構。與 for/in 不同的是 for/of 每次循環取其中的值而不是索引。
https://doc.houdunren.com/js/2%20運算符與流程控制.html#for-in - typeof 用于判斷數據的類型
let a = 1;
console.log(typeof a); //number
let b = "1";
console.log(typeof b); //string
//未賦值或不存在的變量返回undefined
var hd;
console.log(typeof hd);
function run() {}
console.log(typeof run); //function
let c = [1, 2, 3];
console.log(typeof c); //object
let d = { name: "houdunren.com" };
console.log(typeof d); //object
- instanceof 運算符用于檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈上。也可以理解為是否為某個對象的實例,typeof不能區分數組,但instanceof則可以。
let hd = [];
let houdunren = {};
console.log(hd instanceof Array); //true
console.log(houdunren instanceof Array); //false
let c = [1, 2, 3];
console.log(c instanceof Array); //true
let d = { name: "houdunren.com" };
console.log(d instanceof Object); //true
function User() {}
let hd = new User();
console.log(hd instanceof User); //true
- NaN 表示無效的數值,下例計算將產生NaN結果
console.log(Number("houdunren")); //NaN
console.log(2 / 'houdunren'); //NaN
- Date 網站中處理日期時間是很常用的功能
有new沒有new的區別
let now = new Date();
console.log(now);
console.log(typeof date); //object
console.log(now * 1); //獲取時間戳
//直接使用函數獲取當前時間
console.log(Date());
console.log(typeof Date()); //string
//獲取當前時間戳單位毫秒
console.log(Date.now());
- slice (start,end) 截取數組
start 參數開始的元素,并在給定的 end 參數處結束,但不包括。
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3);
- 清空數組
1. user = [];
2. user.length = 0;
3. user.splice(0, user.length);
4.while (user.pop()) {} 使用pop/shift刪除所有元素,來清空數組
- 連接兩個或多個數組
let array = ["hdcms", "houdunren"];
let hd = [1, 2];
let cms = [3, 4];
console.log(array.concat(hd, cms)); //["hdcms", "houdunren", 1, 2, 3, 4]
---------------------------------------------------------------
console.log([...array, ...hd, ...cms]);
---------------------------------------------------------------
array.copyWithin(target, start, end)
- 查找元素
1.indexOf 查找字符串將找不到,因為indexOf 類似于===是嚴格類型約束。
let arr = [7, 3, 2, '8', 2, 6];
console.log(arr.indexOf(8)); // -1
2.lastIndexOf
3.使用 includes 查找字符串返回值是布爾類型更方便判斷 使用includes等不能查找引用類型,因為它們的內存地址是不相等的
4.find 方法找到后會把值返回出來
let arr = ["hdcms", "houdunren", "hdcms"];
let find = arr.find(function(item) {
return item == "hdcms";
});
console.log(find); //hdcms
5.findIndex 返回下標
let arr = [7, 3, 2, '8', 2, 6];
console.log(arr.findIndex(function (v) {
return v == 8;
})); //3
- reduce 使用
reduce
與reduceRight
https://doc.houdunren.com/js/4%20數組類型.html#reduce - symbol
1.Symbol 不能使用 for/in、for/of 遍歷操作
2.可以使用 Object.getOwnPropertySymbols 獲取所有Symbol屬性
3.也可以使用 Reflect.ownKeys(obj) 獲取所有屬性包括Symbol
let user1 = {
name: '李四',
key: Symbol()
}
let user2 = {
name: '李四',
key: Symbol()
}
let grade = {
[user1.key]: { js: 100, css: 90 },
[user2.key]: { js: 900, css: 90 },
};
console.table(grade);
console.table(grade[user1.key]);
image.png
https://doc.houdunren.com/js/5%20Symbol.html#緩存操作
- Set
用于存儲任何類型的唯一值,無論是基本類型還是對象引用。
只能保存值沒有鍵名
嚴格類型檢測如字符串數字不等于數值型數字
值是唯一的
遍歷順序是添加的順序,方便保存回調函數 - WeakSet
1、結構同樣不會存儲重復的值,它的成員必須只能是對象類型的值。
2、WeaSet弱引用
保存的對象不會增加引用計數器,如果一個對象不被引用了會自動刪除。
因為是弱引用 所以也沒有循環便厲的方法
下例中的數組被 arr 引用了,引用計數器+1
數據又添加到了 hd 的WeaSet中,引用計數還是1
當 arr 設置為null時,引用計數-1 此時對象引用為0
當垃圾回收時對象被刪除,這時WakeSet也就沒有記錄了
- classList 給元素添加類
元素.classList.add(''); - this 使用嚴格模式時在全局函數內this為undefined
var hd = '后盾人';
function get() {
"use strict"
return this.hd;
}
console.log(get());
//嚴格模式將產生錯誤 Cannot read property 'name' of undefined
- 對象字面量
下例中的hd函數不屬于對象方法所以指向window
show屬于對象方法執向 obj對象
let obj = {
site: "后盾人",
show() {
console.log(this.site); //后盾人
console.log(`this in show method: ${this}`); //this in show method: [object Object]
function hd() {
console.log(typeof this.site); //undefined
console.log(`this in hd function: ${this}`); //this in hd function: [object Window]
}
hd();
}
};
obj.show();
- 在方法中使用函數時有些函數可以改變this如forEach
let Lesson = {
site: "后盾人",
lists: ["js", "css", "mysql"],
show() {
return this.lists.map(function(title) {
return `${this.site}-${title}`;
}, this);
}
};
console.log(Lesson.show());//['后盾人-js', '后盾人-css', '后盾人-mysql']
- 在父作用域中定義引用this的變量
let Lesson = {
site: "后盾人",
lists: ["js", "css", "mysql"],
show() {
const self = this;
return this.lists.map(function(title) {
return `${self.site}-${title}`;
});
}
};
console.log(Lesson.show());
- 箭頭函數
https://doc.houdunren.com/js/8%20函數進階.html#箭頭函數-2 - apply/call/bind
// call是一個方法 函數的方法
Function.prototype.newCall = function (context) {
//1. 找到未來this的指向,即arguments[0], 如果沒有傳入任何參數 那么我們將this指向window
//如果傳入的類型是string number boolean 我們要對其進行包裝
var target = Object(arguments[0])||window
//2.找到未來要執行的函數 并且改變其this的指向 相當于把this這個未來要執行的函數放在target對象里面 讓函數成為對象的一部分
target.fn = this;
//4.把arguments[0]以外的參數 傳入函數 并且執行該函數
var params = [];
for(var i = 1; i< arguments.length; i++){
params.push(arguments[I]);
}
//var result = target.fn (...params)
var result = eval('target.fn('+params.toString()+')');
//5.刪除目標對象的函數
delete target.fn
return result
};
let obj = {
name: "Jowie",
};
function addAge(age,test) {
this.age = age;
console.log(this);
return this;
}
addAge.newCall(obj,20,30)
Function.prototype.myApply =function(context,arr){
context = Object(context) || window;
context.fn = this;
var result;
if(!arr){
result= context.fn();
}else{
var args = [];
for(var i=0;i<arr.length;i++){
args.push('arr['+i+']');
}
result = eval('context.fn('+args.toString()+')')
}
delete context.fn;
return result;
}
var q = {name:'chuchu'};
var arg1 = 1;
var arg2= [123]
function eat(n,m){
console.log(this,n,m);
}
eat.myApply(q,[arg1,arg2])
//bind方法,是改變當前調用bind方法的函數this指向,但是不會立即執行當前函數,而是返回一個新的函數。并且支持給新的函數傳入參數執行,從而出發之前調用bind方法的函數執行,并且參數透傳進去。bind方法是高階函數的一種
Function.prototype.myBind = function(){
var context = arguments[0];
var self = this;
return function (){
self.myApply(context,arguments)
}
};
var j = {name:1};
var k = [123]
function drink (k){
console.log(this.name,k);
}
var fn = drink.myBind(j);
fn(k);
- 對象是否包含一個屬性
obj.hasOwnProperty
- 使用
in
可以在原型對象上檢測
let obj = {name: "后盾人"};
let hd = {
web: "houdunren.com"
};
//設置hd為obj的新原型
Object.setPrototypeOf(obj, hd);
console.log(obj);
console.log("web" in obj); //true
console.log(obj.hasOwnProperty("web")); //false
- 使用系統提供的API可以方便獲取對象屬性與值
const hd = {
name: "后盾人",
age: 10
};
console.log(Object.keys(hd)); //["name", "age"]
console.log(Object.values(hd)); //["后盾人", 10]
console.table(Object.entries(hd)); //[["name","后盾人"],["age",10]]
Object.getOwnPropertyNames(hd)//["name", "age"]
- Object.assign 函數可簡單的實現淺拷貝,它是將兩個對象的屬性疊加后面對象屬性會覆蓋前面對象同名屬性。
let user = {
name: '后盾人'
};
let hd = {
stu: Object.assign({}, user)
};
hd.stu.name = 'hdcms';
console.log(user.name);//后盾人
- 深淺拷貝
1. 淺拷貝僅僅是指向被拷貝的內存地址,如果原地址中對象被改變了,那么淺拷貝出來的對象也會相應改變。()
2. 我在想如何讓obj1復制obj的對象內容,在我對obj1進行修改時,不影響obj。通過遞歸調用淺拷貝來解決。
//深拷貝 實現
function deepCopy(obj){
let temp = obj.constructor === Array?[]:{};
for(let val in obj){
temp[val] = typeof obj[val] == 'object' ? deepCopy(obj[val]) : obj[val];
}
return temp;
}
console.log(deepCopy(obj));
- 屬性特征
使用 Object.getOwnPropertyDescriptor查看對象屬性的描述
使用Object.defineProperty 方法修改屬性特性
Object.preventExtensions 禁止向對象添加屬性
Object.isExtensible 判斷是否能向對象中添加屬性
Object.seal()方法封閉一個對象,阻止添加新屬性并將所有現有屬性標記為 configurable: false
Object.freeze 凍結對象后不允許添加、刪除、修改屬性,writable、configurable都標記為false
https://doc.houdunren.com/js/10%20對象.html#屬性特征
- 代理攔截(不會)
https://doc.houdunren.com/js/10%20對象.html#閉包訪問器 - 序列化JSON.stringify
序列化是將 json 轉換為字符串
為數據添加 toJSON 方法來自定義返回格式
反序列化
使用 JSON.parse 將字符串 json 解析成對象
let hd = {
"title": "后盾人",
"url": "houdunren.com",
"teacher": {
"name": "向軍大叔",
},
"toJSON": function () {
return {
"title": this.url,
"name": this.teacher.name
};
}
}
console.log(JSON.stringify(hd)); //{"title":"houdunren.com","name":"向軍大叔"}
- mixin
JS不能實現多繼承,如果要使用多個類的方法時可以使用mixin混合模式來完成
const Tool = {
max(key) {
return this.data.sort((a, b) => b[key] - a[key])[0];
}
};
class Lesson {
constructor(lessons) {
this.lessons = lessons;
}
get data() {
return this.lessons;
}
}
Object.assign(Lesson.prototype, Tool);
const data = [
{ name: "js", price: 100 },
{ name: "mysql", price: 212 },
{ name: "vue.js", price: 98 }
];
let hd = new Lesson(data);
console.log(hd.max("price"));
正則表達式
https://doc.houdunren.com/js/14%20正則表達式.htmlPromise(all、allSettled、race)
https://doc.houdunren.com/js/15%20Promise.html#all
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/all任務管理
https://doc.houdunren.com/js/16%20任務管理.html#任務管理