使用者:小號/筆記/javascript
跳至導覽
跳至搜尋
數組
是否改變原始數組
會改變原始數組
一種錯誤寫法:
let a = [1,2,3];
let b = a;
b.push(4);
console.log(a);//输出[1,2,3,4],就nm...
一種正確寫法:
let a = [1,2,3];
let b = [...a];
b.push(4);
console.log(a);//输出[1,2,3]
push()
pop()
shift()
unshift()
splice()
reverse()
sort()
forEach()
不會改變原始數組
filter()
concat()
slice()
join()
map()
every()
some()
indexOf()
構造函數
基礎
摘自 https://blog.csdn.net/sinat_21742529/article/details/83659459 。
- 使用new操作符調用函數
例子:
function Person(name){
this.name = name;
this.say = function(){
return "I am " + this.name;
}
}
var person1 = new Person('nicole');
person1.say(); // "I am nicole"
用new調用構造函數,函數內部會發生如下變化:
創建一個this變量,該變量指向一個空對象。並且該對象繼承函數的原型;
屬性和方法被加入到this引用的對象中;
隱式返回this對象(如果沒有顯性返回其他對象)
用偽程序來展示上述變化:
function Person(name){
// 创建this变量,指向空对象
var this = {};
// 属性和方法被加入到this引用的对象中
this.name = name;
this.say = function(){
return "I am " + this.name;
}
// 返回this对象
return this;
}
可以看出,用new調用構造函數,最大特點為,this對象指向構造函數生成的對象,所以,person1.say()
會返回字符串:「I am nicole」。
小貼士
如果指定了返回對象,那麼,this對象可能被丟失。
function Person(name){
this.name = name;
this.say = function(){
return "I am " + this.name;
}
var that = {};
that.name = "It is that!";
return that;
}
var person1 = new Person('nicole');
person1.name; // "It is that!"
- 直接調用函數
如果直接調用函數,那麼,this對象指向window,並且,不會默認返回任何對象(除非顯性聲明返回值)。
還是拿Person函數為例,直接調用Person函數:
var person1 = Person('nicole');
person1; // undefined
window.name; // nicole
可見,直接調用構造函數的結果,並不是我們想要的。
自有屬性
function C(a) {
this.a = a;
this.b = 1;
}
let d = new C("e");
a
和b
被叫做自有屬性。
用.hasOwnProperty()
判斷是否為自有屬性。
let o = [];
for (let i in d) {
if(d.hasOwnProperty(i)) {
o.push(i);
}
}
console.log(o);//["a","b"]
原型屬性
prototype
是一個可以在所有C
實例之間共享的對象。
C.prototype.f = 2;
console.log(d.f);//2
添加多個屬性:
C.prototype.f = 2;
C.prototype.g = function() {
console.log("g");
}
C.prototype.h = function() {
console.log("h" + this.a);
}
//等价于
C.prototype = {
f: 2,
g() {
console.log("g");
},
h() {
console.log("h" + this.a);
}
};
constructor
屬性
let d = new C("e");
console.log(d.constructor === C);//返回true
注意:
C.prototype = {
f: 2,
g() {
console.log("g");
},
h() {
console.log("h" + this.a);
}
};
let d = new C("e");
console.log(d.constructor === C);//返回false
console.log(d.constructor === Object);//返回true
console.log(d instanceof C);//返回true
所以你應該在給新對象重新設置過原型對象時,再定義一個constructor
屬性:
C.prototype = {
constructor: C,
f: 2,
g() {
console.log("g");
},
h() {
console.log("h" + this.a);
}
};
原型鏈/繼承
使用.isPrototypeOf()
判斷原型鏈:
console.log(C.prototype.isPrototypeOf(d));//返回true
//原型链的最顶层Object
console.log(Object.prototype.isPrototypeOf(C.prototype));//返回true
舉個.map()
函數幾乎毫不相干的例子:
let x = [9,81,625]
Array.prototype.myMap = function(callback) {
const newArray = [];
for(let i of this){
newArray.push(callback(i))
}
return newArray;
};
let s = x.map(Math.sqrt);//等价于
let s = x.myMap(Math.sqrt);
console.log(s)//[3,9,25]
用繼承避免重複:
A.prototype = {
constructor: A,
x() {
console.log("c");
}
};
B.prototype = {
constructor: B,
x() {
console.log("c");
}
};
//等价于
function C() {};
C.prototype = {
constructor: C,
x() {
console.log("c");
}
};
A.prototype = Object.create(C.prototype);
B.prototype = Object.create(C.prototype);
A.prototype = {
constructor: A
};
B.prototype = {
constructor: B
};
更多見#類繼承
Mixin
添加共同行為
let aMixin = (d) => {
d.shit = () => {
console.log("oh my god");
}
};
let b = {
r: "t",
e: 2
};
let c = {
i: "o",
u: 7
};
//将shit()方法分配给对象
aMixin(bird);
aMixin(plane);
bird.shit();//"oh my god"
plane.shit();//"oh my god"
類
Get 與 Set
- Getter 函數的作用是可以讓對象返回一個私有變量,而不需要直接去訪問私有變量。
- Setter 函數的作用是可以基於傳進的參數來修改對象中私有變量。 這些修改可以是計算,或者是直接替換之前的值。反正我沒看懂。
// 个人给出自己理解的例子
class a {
constructor(d) {
this.e = d;
}
get b() {
return this.e + 10;
}
set b(c) {
/*return无效*/ this.e = c - 1;
}
}
let t = new a(3); // 此处 { e: 3 },随后t: { b: ()=> { return this.e + 10 }, e: 3 },得t: { b: 13, e: 3 }
let f = t.b;
let r = t.e;
t.b = 20; // 此处 { e: (c = t.b)=> { this.e = c - 1 } },得{ e: 19 },随后t: { b: ()=> { return this.e + 10 }, e: 19 },得t: { b: 29, e: 19 }
let g = t.b;
let l = t.e;
console.log(f, r, g, l); // 输出 13 3 29 19
類繼承
與原型繼承同理,而class
作為語法糖更好理解。
class A {
constructor(name) {
this._name = name;
}
aunction() {
return this._name;
}
}
class B extends A {
constructor(name, age) {
super(name);//调用父类方法
this._age = age;
}
bunction() {
return this.aunction() + this._age ;
}
}
let c = new A("a", "b");
let d = new B("a", "b");
console.log(c.aunction());//"a"
console.log(d.bunction());//"ab"
使用extends
進行類繼承,使用super()
調用父類構造方法。