We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
在Javacript中,有两种类型的值,基本类型)和 引用类型 (对象), 基本类型 (primitive type)有Undifined, Null, Boolean, Number, String,一般存储在栈stack中,而对象分为普通对象和函数对象,存储在堆heap中,Object和Function是JS自带的函数对象。举例如下:
function f1() {} // 注:函数作为构造子,一般情况首字母要大写 var f2 = function() {} var f3 = new Function('str', 'console.log(str)'); var o1 = new f1(); var o2 = {}; var o3 = new Object(); console.log(typeof(Object)); //function console.log(typeof(Function)); //function console.log(typeof(f1)); //function console.log(typeof(f2)); //function console.log(typeof(f3)); //function console.log(typeof(o1)); //object console.log(typeof(o2)); //object console.log(typeof(o3)); //object
显而易见,函数对象就是通过new Function()创建出来的,Object,Function本身也是。 而普通对象则是由函数对象通过new关键字创建出来的。
在javascript中,每当定义一个对象(函数)时,都会包含一些预定义的属性。其中,函数对象的一个属性就是prototype,而普通对象没有prototype,但有__proto__属性,它指向创建它的函数的prototype属性。
原型对象其实就是普通对象(Function.prototype除外,它很特殊,它是函数对象,但没有prototype属性)
function f1() {} console.log(f1.prototype) //f1{} console.log(typeof f1.prototype) //object console.log(typeof Function.prototype) //function console.log(typeof Object.prototype) //object console.log(Function.prototype.prototype) //undifined
可以看出f1.prototype就是函数f1的一个实例对象,函数f1在创建的时候,就将它的一个实例对象赋值给其prototype属性。即:
var temp = new f1(); f1.prototype = temp;
所以Function.prototype为什么是函数对象就迎刃而解了。
var temp = new Function(); Function.prototype = temp;
无论普通对象还是函数对象 都有一个__proto__属性,它指向创建它的函数对象的prototype对象 e.g.
var Person = function(name) { this.name = name; } Person.prototype.showName = function() { console.log(this.name); } var xiaoming = new Person("xiaoming"); xiaoming.showName(); console.log(xiaoming.__proto__ === Person.prototype); //true console.log(Person.prototype.__proto__ === Object.prototype); //true console.log(Object.prototype.__proto__); //null
我们把这个由_proto__串起来一直到Object.prototype._proto === null的链叫做原型链。 所以说,原型链的形成真正靠的是_proto_,而不是prototype。
原型对象prototype中都有个预定义的constructor属性,用来引用它的函数对象,这是一种循环引用。
Person.prototype.constructor === Person; //true Function.prototype.constructor === Function; //true Object.prototype.constructor === Object; //true
所以要查找一个对象的constructor,只需找到它原型链上遇到的第一个constructor属性指向的对象。
下图是原型链的汇总图:
虽然JavaScript是一种object-based的语言,遇到的所有东西几乎都是对象,但是它又不是一种真正的oop语言,因为没有class这个概念。、 所以要实现oop,我们需要将属性和方法封装成一个对象,即 Encapulation,e.g.
// 新建constructor var Cat = function(name, color) { this.name = name; this.color = color; } // 把不变的属性和方法放在原型对象中以节约内存 Cat.prototype.type = "猫科动物"; Cat.prototype.eat = function() { console.log("吃老鼠"); } var cat1 = new Cat("cat1", "red"); var cat2 = new Cat("cat2", "blue"); console.log(cat1.eat === cat2.eat); // true console.log(Cat.prototype.isPrototypeOf(cat1)); // true console.log(cat1.hasOwnProperty("name")); //true console.log(cat1.hasOwnProperty("type")); //false console.log("name" in cat1); //true console.log("type" in cat1); //true console.log(cat1.__proto__ === cat2.__proto__); //true
继承机制 e.g.
var Parent = function(name) { this.name = name; } Parent.prototype.sayName = function() { console.log(this.name); } var Child = function(name, color) { this.name = name; this.color = color; } Child.prototype = new Parent(); Child.prototype.constructor = Child; Child.prototype.sayColor = function() { console.log(this.color); } var cat = new Child("cat", "white"); cat.sayName(); cat.sayColor(); console.log(cat.__proto__);
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } } class ColorPoint extends Point { constructor(color, x, y) { super(x, y); /* 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。*/ this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } }
The text was updated successfully, but these errors were encountered:
WarpPrism
No branches or pull requests
基础概念
在Javacript中,有两种类型的值,基本类型)和 引用类型 (对象), 基本类型 (primitive type)有Undifined, Null, Boolean, Number, String,一般存储在栈stack中,而对象分为普通对象和函数对象,存储在堆heap中,Object和Function是JS自带的函数对象。举例如下:
显而易见,函数对象就是通过new Function()创建出来的,Object,Function本身也是。
而普通对象则是由函数对象通过new关键字创建出来的。
原型对象
在javascript中,每当定义一个对象(函数)时,都会包含一些预定义的属性。其中,函数对象的一个属性就是prototype,而普通对象没有prototype,但有__proto__属性,它指向创建它的函数的prototype属性。
原型对象其实就是普通对象(Function.prototype除外,它很特殊,它是函数对象,但没有prototype属性)
可以看出f1.prototype就是函数f1的一个实例对象,函数f1在创建的时候,就将它的一个实例对象赋值给其prototype属性。即:
所以Function.prototype为什么是函数对象就迎刃而解了。
原型链
无论普通对象还是函数对象 都有一个__proto__属性,它指向创建它的函数对象的prototype对象 e.g.
我们把这个由_proto__串起来一直到Object.prototype._proto === null的链叫做原型链。
所以说,原型链的形成真正靠的是_proto_,而不是prototype。
原型对象prototype中都有个预定义的constructor属性,用来引用它的函数对象,这是一种循环引用。
所以要查找一个对象的constructor,只需找到它原型链上遇到的第一个constructor属性指向的对象。
下图是原型链的汇总图:

prototype与面向对象程序设计
虽然JavaScript是一种object-based的语言,遇到的所有东西几乎都是对象,但是它又不是一种真正的oop语言,因为没有class这个概念。、
所以要实现oop,我们需要将属性和方法封装成一个对象,即 Encapulation,e.g.
继承机制 e.g.
ES6 class语法糖
The text was updated successfully, but these errors were encountered: