js面向对象

构造函数

  • 默认函数首字母大写
  • 构造函数并没有显示返回任何东西。new 操作符会自动创建给定的类型并返回他们,当调用构造函数时,new会自动创建this对象,且类型就是构造函数类型。
  • 也可以在构造函数中显示调用return.如果返回的值是一个对象,它会代替新创建的对象实例返回。如果返回的值是一个原始类型,它会被忽略,新创建的实例会被返回。
  • 因为构造函数也是函数,所以可以直接被调用,但是它的返回值为undefine,此时构造函数里面的this对象等于全局this对象。this.name其实就是创建一个全局的变量name。在严格模式下,当你补通过new 调用Person构造函数会出现错误。

用new操作符调用一个函数的时候:

  • 函数内部创建一个局部变量,是一个空对象{};var obj ={};obj.proto = CO.prototype;
  • 函数将自己的上下文设置为这个{};CO.call(obj);
  • 函数执行所有语句;
  • 函数将return 这个对象{},函数将把自己的上下文返回。return obj;
1
2
3
4
5
6
7
8
9
10
11
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
var p1 = new People('小明', 30, '男');
var p2 = new People('小红', 28, '女');
console.log(p1); //People{name: "小明", age: 30, sex: "男"}
console.log(p2); //People{name: "小红", age: 28, sex: "女"}

原型链

每一个构造函数都有一个属性prototype,指向一个对象。实例化这个对象的时候,每一个实例的proto属性也指向这个对象。

1
2
3
4
5
6
function F() {
this.a = 1;
}
var o = new F();
console.log(F.prototype === o.__proto__); //true

任何函数都有prototype,是一个空对象。不是函数一定没有prototype属性,prototype属性的值是一个对象。这个函数new操作符实例化的proto指向这个对象。

proto

W3C是没有规定一个元素的原型链有一个可见的属性,Chrome游览器特有的proto属性,为了方便初学者学习和使用方便,其他游览器有原型链的机制,但是看不到这个属性。一旦原型链产生不可更改。
ECMAScript2016中,提供了Object.create()函数,可以指定一个对象为原型对象,来创建新对象。

1
2
3
4
5
var obj1 = {"a": 1, "b":2};
var obj2 = Object.create(obj1);
console.log(obj2.__proto__ === obj1);//true
console.log(obj2.a);//1
console.log(obj2.b);//2

写一个兼容的create()

1
2
3
4
5
6
7
8
9
function Create(obj) {
//虚构一个构造函数
function f(){};
//f的prototype指向传人的对象
f.prototype = obj;
//实例化f,实例化后的f的__proto__ 就是指向obj
return new f();
}

构造函数和实例的关系

构造函数: 抽象,定义的是一类对象应该具有什么属性,什么方法,描述规则。
实例: 具体,创建出来的一个个具体的实例,拥有属性,并能调用方法。
构造函数中,用prototype来定义方法,定义的是构造函数的实例的方法,不是构造函数的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Dog(name, weight) {
this.name = name;
this.weight = weight;
}
Dog.prototype.eat = function() {
console.log(this.name + 'eating');
this.weight += 10;
}
var dog = new Dog('小黄', 40);
dog.eat();//小黄eating
dog.weight; //50

内置构造函数

Object函数

系统内置了一个Object函数,可以直接new,返回一个空对象。

1
2
var o = new Object();
console.log(o); //{}

Object.prototype是所有对象的原型链终点。

Function 函数

系统内置了一个Function的构造函数,用于构造函数。所有的function字面量都是他的实例。

1
2
3
4
5
6
7
function sum(a, b){
console.log(a+b);
}
var sum2 = new Function("a", "b", "console.log(a+b)");
sum(4, 5);//9
sum2(4, 5);//9

任何函数都是Function的实例。(包括Object和Function自己)

Array函数

Array是系统内置的数组构造函数,用于构造数组。

RegExp函数

任何一个正则表达式都是RegExp的实例。
var reg = /\d/g;
等价于
var reg = new RegExp(“\d”,”g”);

Number 函数

Number函数是一个系统内置的构造函数,用于创建数字对象。

1
2
3
var a = new Number(3);
console.log(a);//3
console.log(typeof a); //object

用Number构造函数创建数字的时候,得到的是一个对象,这个对象的原始值属性primitiveValue是3,这个属性不能被枚举。

String函数

String函数是系统内置构造函数,用于创建字符串对象。

1
2
var str = new String("hello");
console.log(str);

Boolean函数

1
2
var a = new Boolean(false);
console.log(a);

对象的种类的归属辨别

任何一个构造函数的prototype上都有一个constructor属性,指向构造函数,这个属性不可枚举。

1
2
3
4
5
6
function People() {
}
var p1 = new People();
console.log(People.prototype.constructor == People);// true
console.log(p1.constructor == People);//true

鸭式辨型

James Whitcomb Riley提出像鸭子一样走路、游泳和嘎嘎叫的鸟就是鸭子

滑动门js面向对象实例

github地址

在线演示地址