JavaScript面向对象主要知识点小结,基于ECMAScript 5.javascript
function People(name){ //this能够理解为经过new即将建立的对象 this.name = name; } //将类实例化 var person = new People('Cassie Xu'); console.log(person.name);
给一个对象赋予属性或者方法java
function People(name) { this.name = name; this.greet = function() { console.log('Hello, my name is ' + this.name + '!'); }; } var person = new People('Cassie Xu'); person.greet();
why we use prototype? -> 便于方法的重用
与构造函数模式相比,使用原型对象的好处是能够让全部对象实例共享它所包含的属性和方法。
运行时没找到函数的方法时,对象会首先找它的类的prototype方法
Demo1git
function People(name) { this.name = name; } People.prototype = { greet: function() { console.log('Hello, my name is ' + this.name + '!'); } }; var person = new People('Cassie Xu'); person.greet(); //在每一个实例化后的对象都会有一个__proto__属性,类会将它的prototype赋给实例 //实例化一个对象时,People这个类首先会将person的__proto属性指向People.prototype console.log(person.__proto__ === People.prototype); // true
Demo2github
var a = { foo: 1 }; var b = { bar: 2 }; b.__proto__ = a; //b自己没有foo属性,可是b会继续寻找__proto__属性 console.log(b.foo); // 1 console.log(b.bar); // 2 var a = {}; console.log(a.__proto__); // {} console.log(a.__proto__.__proto__); // null
var a = {}; console.log(a.__proto__); // {} console.log(a.__proto__.__proto__); // null
Demo1数组
function Parent(){} Parent.prototype = { greet: function(){ console.log('hello world'); } } function Child(){} //此方法适用于父类Child不须要传参数 Child.prototype = new Parent(); var c = new Child(); //c首先寻找自身的方法,没有great,因此找Child的原型方法,而Child.prototype等于Parent方法 c.greet(); //console.log('hello world');
上面的例子若是Parent有参数,将存在如下问题:闭包
function Parent(a, b) {} Parent.prototype.greet = function() { console.log('JavaScript rocks'); } function Child(a, b) {} Child.prototype = new Parent(); //something wrong?->new Parent()不能传参数,不然参数一直不变 var child = new Child(); child.greet();
Demo2
解决父类参数问题app
function Parent() { this.name = 'xxx', this.date = 'xxx' } Parent.prototype.greet = function() { console.log('JavaScript rocks'); } function Child() {} //此方法适用于 Child.prototype = Object.create(Parent.prototype); //硬记的知识 Child.prototype.constructor = Child; var child = new Child(); child.greet();
Demo3:继承的一个实例
建立一个矩形dom
function Rect(width,height){ this._setupDOM(width,height); } Rect.prototype._setupDOM = function(width,height){ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; }; Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; function BlueRect(width,height){ BlueRect._super.apply(this,arguments); } BlueRect.prototype = Object.create(Rect.prototype); BlueRect.prototype.constructor = BlueRect; BlueRect._super = Rect; BlueRect.prototype._setupDOM = function(width,height){ BlueRect._super.prototype._setupDOM.apply(this,arguments); this._dom.style.backgroundColor = 'blue'; }; var br = new BlueRect(200,300); br.appendToBody();
Demo:函数
function Rect(width,height){ //私有属性加_ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; this._dom.style.backgroundColor = 'red'; } Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; var rect = new Rect(100,100); rect.appendToBody();
修改上面demo:this
function Rect(width,height){ this._setupDom(width,height); } Rect.prototype._setupDom = function(width,height){ //私有属性加_ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; this._dom.style.backgroundColor = 'red'; }; Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; var rect = new Rect(100,100); rect.appendToBody(); var person = { firstName: "Penelope", lastName: "Barrymore", sayFullName: function () { console.log(this.firstName + " " + this.lastName); //=> "Penelope Barrymore" console.log(person.firstName + " " + person.lastName); //=> "Penelope Barrymore" } }; person.sayFullName();
严格模式下的this
funtion foo(){ 'use strict'; console.log(this) //undefined }
function foo(a, b) { console.log(this); console.log(a + b); } var fooBinding = foo.bind({ name: 'Cassie Xu' }); fooBinding(1, 2);
上面code将输出
[object Object] { name: "Cassie Xu" }
call/apply方法都为调用Object方法,区别是apply将全部参数放到一个数组中去
function foo(a, b) { console.log(this); console.log(a + b); } foo.call({name:'Cassie Xu'}, 1, 2); foo.apply({name:'Cassie Xu'}, [1, 2]);
why we use it? ->避免泄露全局变量
(function(c){ var a = 1; var b = 2; console.log(a+b+c); })(3) // c = 3
var a = {}; a.foo = function(callback) { // do something and call callback in whatever way } a.bar = function() { this.num = 1; var that = this; //闭包,这里that能够访问到a.bar的做用域 this.foo(function(newNum) { that.num = newNum; }); console.log(this.num); } a.bar();
本文转自 JavaScript面向对象知识点小结