4. 原型与正则


创建对象

1
2
3
4
5
6
7
8
9
10
11
var o=new Object();

var o1={};

var o2={
xxx:xxx
};

class o3{

}

Object.create();

根据已有对象创建对象的__proto__

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var o1={
name:'lisi',
age:23
};
var o2=Object.create(o1);
//使用o1来给o2创建__proto__

console.log(o2.__proto__==o1);//true

console.log(o2.name);//相当于
console.log(o2.__proto__.name);

var o2={
__proto__:{
name:'lisi',
age:23
}
};

proto:当你发现一个变量有____时说明在提示你这个变量时私有的

原型以及原型链

被设计用来做继承

1
2
3
4
5
6
7
8
9
function Animal(name){
this.name=name;
}
//prototype也是一个对象,我们可以在这个对象下面创建属性和方法
Animal.prototype.shout=function(){
console.log(this.name);
}
var a1=new Animal('mimi');
a1.shout();

es6之前定义一个类的方法是

  1. 首先写一个函数,充当“构造函数”,有参数,有属性
  2. 通过原型对象来写这个类的“方法”
  3. 使用时在函数里写参数,“构造方法”通过函数调用this来给对象的属性赋值

所谓自由属性就是在构造函数中定义的属性

1
2
3
4
5
6
7
8
9
function Person(name){
this.name=name;
}
Person.prototype.age=23;
Person.prototype.brother={
name:'haha'
};
var p1=new Person('lisi');
p1.age=45;//相当于在p1对象中添加了一个自由的属性age

new出来的对象,{}里面打印出来的是属于对象本身的属性,是自由属性。当访问对象的属性时如果自身有的话就打印,如果没有就在对象的原型进行查找,如果还没有就去原型的原型找,最后找到Object下面的prototype还没有就返回undefined

原型中的属性被改了,所有继承该原型的对象都会被修改

但是由于无法修改基本数据类型(因为js的语法,修改即创建,导致只有引用类型会被修改,一个点不改,多个点就改了)

正常继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Animal{
name;
contructor(name){
this.name=name;
}
shout(){
console.log(this.name+"is shouting");
}
}

class Cat extends Animal{

}

var cat1=new Cat("mimi");
cat1.shout();

几个方法,几个对象

1
2
3
var test=function (){}
//底层是
var test=new Function();

例子:

1
2
3
4
5
6
7
function Person(name){
this.name=name;
this.sleep=function (){
console.log(this.name+"is sleeping...");
}
}
var p1new Person('lisi');//创建了两个对象

结论:不要将属性放在原型中,因为修改一个都会被修改,并且不要讲方法放在构造函数中,因为每次创建对象的时候,每个方法都会创建一个对象,放在原型里的话只有页面加载完毕会创建,其余不创建

重点:所有的对象都有一个__proto__的属性,该属性是一个普通的对象,所有的函数都有一个prototype属性,该属性是一个普通的对象。所有对象的__proto__属性指向他的函数的prototype

1
prototype专门在原型链里加东西用的,__proto__不要随便动

es6之前的继承

1
2
3
4
5
6
7
8
9
10
11
12
13
function Animal(name){
this.name=name;
}
Animal.prototype.shout=function(){
console.log(this.name+'is shouting...');
}
function Cat(name){
Animal.call(this,name);
}
Cat.prototype=new Animal('xxxx');//继承了方法,但是也继承了属性,需要改进
Cat.prototype=Cat;
var car1=new Cat();
console.log(cat1);

修正(利用寄生组合方式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Animal(name){
this.name=name;
}
Animal.prototype.shout=function(){
console.log(this.name+'is shouting...');
}
function Cat(name){
Animal.call(this,name);
}
//寄生组合方式
Cat.prototype=Object.create(Animal.prototype);
Cat.prototype.constructor=Cat;
var car1=new Cat();
console.log(cat1);

对象拷贝

1
2
3
4
5
6
7
8
var o1={
name:'lisi',
age:23
};
var o2=o1;
o1.name='wangwu';
console.log(o2.name);//wangwu
//原因是指针的拷贝,而不是对象的重新创建

isPrototype

复习

1
2
3
4
5
6
7
8
9
10
11
12
13
//首先一个父类parent
function Parent(name){
this.name=name;
}
Parent.prototype.eat=function (){
console.log(this.name+"is eating...");
}
function Son(name){
Parent.call(this,name);
}
Son.prototype=Object.create(Parent.prototype);
Son.prototype.constructor=Son;
var s=new Son('lili');

1月10日复习

  1. 被设计用了继承
  2. 每个函数都有一个prototype
  3. 函数也是对象,对象是通过new Function()创建
  4. 对象是通过new Object();实现
  5. 原型链查找,对象是通过__proto__查找的

Author: pkq
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source pkq !
  TOC