面向对象的程序设计

210 阅读7分钟

「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」。

object对象
  • new关键字代表的是新开辟一块内存空间
  • 没有被引用的内存空间,会在适当的时候被销毁

    • 两句代码含义等同

      • var person = new Object();
      • var person = {};
  • 访问对象的属性除了用 对象引用.属性 key以外,还可以使用对象引用[属性key]

new 原理详细解析

  • 无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
  • 在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针(就是指向新创建的函数)。
  • 通过这个构造函数(原型对象的构造函数),可以继续为原型对象添加其他属性和方法。
  • 当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版管这个指针叫 [[Prototype]]。脚本中没有标准的方式访问[[Prototype]],但FirefoxSafariChrome在每个对象上都支持一个属性__proto__;而在其他实现中,这个属性对脚本是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例和构造函数的原型对象之间,而不是存在于实例和构造函数之间
new创建对象的步骤

  • 创建一个新的对象
  • 将构造函数的作用域赋给新对象
  • 执行构造函数的代码,为这个新对象添加属性
  • 返回新对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this.name);
};
}

function createPerson(P) {
// 创建一个新对象
var o = new Object();
// 获取传递给Person函数的参数
var args = Array.prototype.slice.call(arguments, 1);
// 新对象的__proto__属性指向Person的原型对象
o.__proto__ = P.prototype;
// Person的原型对象的constructor指向Person
P.prototype.constructor = P;
// 把Person构造函数的作用域赋给新对象
// 给这个新对象添加属性(name,age,say)
P.apply(o, args);
// 返回这个新对象
return o;
}

var p = createPerson(Person, 'wang', 35);
  • function构造器

    • 共同点:
      • 动态创建一块内存空间,闭包
    • 不同点:
      • 函数调用是没有办法拿到空间的地址的,而且这块地址是一块临时地址,执行完函数之后,就会销毁
      • new开辟内存空间,把这块空间的地址返回,这块空间就有可能长期的被引用
  • prototype原型
    • 通过原型使通过同样一个构造器所new(创建)出来的对象具有相同的属性和行为
    • prototype本质就是一个对象
  • foreach
  • this 指代当前创建的这块内存 this.name=name 指代当前内存中的这个name属性 接收外界传过来的值
  • 继承
多种构造函数

传统的创建对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

var person = new Object();

person.name = “lancer”;

person.age = 24;

person.job = “UI”;

person.sayName = function(){

alert(this.name);

}

person.sayName();
工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

function createPerson(name,age,job){

var o = new Object();

o.name = name;

o.age = age;

o.job = job;

o.sayName = function(){

alert(o.name);

}

return o;

}

var person1 = createPerson(“lancer”,24,”UI”);

person1.sayName();
构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

function Person(name,age,job){

this.name = name;

this.age = age;

this.job =job;

this.sayName = function(){

alert(this.name)

}

}

var person1 = createPerson(“lancer”,24,”UI”);

person1.sayName();
原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

function Person(){

}

Person.prototype.name =”lancer”;

Person.prototype.age =24;

Person.prototype.job = “UI”;

Person.prototype.sayName = function(){

alert(this.name)

}

var person1 = new Person();

person1.sayName();

var person2 = new Person();

person2.name =”lara”

person2.sayName();
简单原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

function Person(){

}

Person.prototype = {

name : “lancer”,

age : 24,

job : “UI”,

sayName : function(){

alert(this.name)

}

};

var person1 = new Person();

person1.sayName();
构造函数和原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

function Person(name,age,job){

this.name = name;

this.age = age;

this.job =job;

}

Person.prototype = {

constructor :Person,

sayName : function(){

alert(this.name)

}

};

var person1 = new Person(“lancer”,”24″,”UI”);

person1.sayName();
动态原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

function Person(name,age,job){

this.name = name;

this.age = age;

this.job =job;

}

if(typeof this.sayName !=”function”){

Person.prototype = {

constructor :Person,

sayName : function(){

alert(this.name)

}

};

}

var person1 = new Person(“lancer”,”24″,”UI”);

person1.sayName();
稳妥构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var Person = function(name,age,job){

var O = new Object();

O.sayName = function(){

alert(name);

};

return O

}

var person1 = Person(“lancer”,24,”UI”);

person1.sayName();

其他:


  • 函数调用后一定有返回值,没有返回值就是undefined
  • new关键字代表的是新开辟一块内存空间
  • 没有被引用的内存空间,会在适当的时候被销毁
    • 两句代码含义等同
    • var person = new Object();
    • var person = {};
    • 访问对象的属性除了用 对象引用属性key以外,还可以使用对象引用[属性key]
  • a.function构造器
    • 共同点:
      • 动态创建一块内存空间,闭包
    • 不同点:
      • 函数调用是没有办法拿到空间的地址的,而且这块地址是一块临时地址,执行完函数之后,就会销毁
      • new开辟内存空间,把这块空间的地址返回,这块空间就有可能长期的被引用
  • b.prototype原型
    • 通过原型使通过同样一个构造器所new(创建)出来的对象具有相同的属性和行为
    • prototype本质就是一个对象
  • c.foreach
  • c.this
  • d.继承

知识点:


1.prototype内存解析


  • prototype是原型,是一块所有对应构造器创建的对象都共享的内存空间
  • 在面向对象设计程序的时候,属性应该是对应的空间的,而功能应该是prototype公共空间的

2.通过prototype扩展功能


  • 所有的构造器都是继承于Object构造器的,因此只要Object的原型里有的功能,所有的对象都有
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//多个对象的构造 以及 多个对象之间如何建立联系
function Student(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;

}
function Bingqilin(name){
this.name = name;
}
function Game(name){
this.name = name;
}
function Hour(time){
this.time = time;
}
Student.prototype = {

eat:function(b){
alert(this.name+"喜欢吃"+b.name);
},
mess:function(){
alert(this.name+"的信息:"+this.age+','+this.sex);
},
sleep:function(h){
alert(this.name+"每天睡,"+h.time+'小时');
},
work:function(h){
alert(this.name+"每天工作,"+h.time+'小时');
},
like:function(g){
alert(this.name+"喜欢打,"+g.name);
}

}
var s = new Student("小明",22,"男");

var b = new Bingqilin("黑色的冰淇淋");
s.eat(b);//小明喜欢吃黑色的冰淇淋

var g = new Game("英雄联盟");
s.like(g);//把对象的地址发送给like的参数即可访问构造函数Game的name属性

var h = new Hour(10);
s.sleep(h);
s.work(h);