用户:小号/笔记/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()
调用父类构造方法。