赞
踩
// 1. 利用 new Object() 创建对象 var obj1 = new Object(); // 2. 利用 对象字面量创建对象 var obj2 = { }; // 3. 利用构造函数创建对象 function Star(uname, age) { this.uname = uname; this.age = age; this.sing = function() { console.log('我会唱歌'); } } var ldh = new Star('刘德华', 18); var zxy = new Star('张学友', 19); console.log(ldh); ldh.sing(); zxy.sing();
// 构造函数中的属性和方法我们称为成员, 成员可以添加 function Star(uname, age) { this.uname = uname; this.age = age; this.sing = function() { console.log('我会唱歌'); } } var ldh = new Star('刘德华', 18); // 1.实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员 // 实例成员只能通过实例化的对象来访问 console.log(ldh.uname); ldh.sing(); // console.log(Star.uname); // 不可以通过构造函数来访问实例成员 // 2. 静态成员 在构造函数本身上添加的成员 sex 就是静态成员 Star.sex = '男'; // 静态成员只能通过构造函数来访问 console.log(Star.sex); console.log(ldh.sex); // 不能通过对象来访问
构造函数方法很好用,但是存在浪费内存的问题。
// 1. 构造函数的问题. function Star(uname, age) { this.uname = uname; this.age = age; // this.sing = function() { // console.log('我会唱歌'); // } } Star.prototype.sing = function() { console.log('我会唱歌'); } var ldh = new Star('刘德华', 18); var zxy = new Star('张学友', 19); console.log(ldh.sing === zxy.sing); ldh.sing(); zxy.sing(); // 2. 一般情况下,公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上
__proto__
注意:该特性不再被推荐,而推荐
Object.getPrototypeOf(object)
方法,其返回指定对象的原型
__proto__
指向构造函数的 prototype 原型对象,之所以对象可以使用构造函数prototype 原型对象的属性和方法,就是因为对象有 __proto__
原型的存在。__proto__
对象原型和原型对象 prototype 是等价的__proto__
对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性function Star(uname, age) { this.uname = uname; this.age = age; } Star.prototype.sing = function() { console.log('我会唱歌'); } var ldh = new Star('刘德华', 18); var zxy = new Star('张学友', 19); ldh.sing(); console.log(ldh); // 对象身上系统自己添加一个 __proto__ 指向构造函数的原型对象 prototype console.log(ldh.__proto__ === Star.prototype); // 方法的查找规则: 首先先看ldh 对象身上是否有 sing 方法,如果有就执行这个对象上的sing // 如果没有sing 这个方法,因为有__proto__ 的存在,就去构造函数原型对象prototype身上去查找sing这个方法
__proto__
)和构造函数(prototype
)原型对象里面都有一个属性 constructor 属性 ,constructor 称为构造函数,因为它指回构造函数本身。function Star(uname, age) { this.uname = uname; this.age = age; } // 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数 // Star.prototype.sing = function() { // console.log('我会唱歌'); // }; // Star.prototype.movie = function() { // console.log('我会演电影'); // } Star.prototype = { // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数 constructor: Star, sing: function() { console.log('我会唱歌'); }, movie: function() { console.log('我会演电影'); } } var ldh = new Star('刘德华', 18); var zxy = new Star('张学友', 19); console.log(Star.prototype); console.log(ldh.__proto__); console.log(Star.prototype.constructor); console.log(ldh.__proto__.constructor);
function Star(uname, age) { this.uname = uname; this.age = age; } Star.prototype.sing = function() { console.log('我会唱歌'); } var ldh = new Star('刘德华', 18); // 1. 只要是对象就有__proto__ 原型, 指向原型对象 console.log(Star.prototype); console.log(Star.prototype.__proto__ === Object.prototype); // 2. Star原型对象里面的__proto__原型指向的是 Object.prototype console.log(Object.prototype.__proto__); // 3. Object.prototype原型对象里面的__proto__原型 指向为 null
① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
③ 如果还没有就查找原型对象的原型(Object的原型对象)。
④ 依此类推一直找到 Object 为止(null)。
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。
function Star(uname, age) { this.uname = uname; this.age = age; } Star.prototype.sing = function() { console.log('我会唱歌'); } Star.prototype.sex = '女'; // Object.prototype.sex = '男'; var ldh = new Star('刘德华', 18); ldh.sex = '男'; console.log(ldh.sex); console.log(Object.prototype); console.log(Star.prototype); console.log(ldh.toString());
function Star(uname, age) { this.uname = uname; this.age = age; } var that; Star.prototype.sing = function() { console.log('我会唱歌'); that = this; } var ldh = new Star('刘德华', 18); // 1. 在构造函数中,里面this指向的是对象实例 ldh ldh.sing(); console.log(that === ldh); //true // 2.原型对象函数里面的this 指向的是 实例对象 ldh
Array.prototype = {}
,只能是 Array.prototype.xxx = function(){}
的方式。// 原型对象的应用 扩展内置对象方法 Array.prototype.sum = function() { //点的方式是在原来propotype对象基础上追加方法 var sum = 0; for (var i = 0; i < this.length; i++) { sum += this[i]; } return sum; }; // Array.prototype = { //用对象这种方式会覆盖propotype对象 // sum: function() { // var sum = 0; // for (var i = 0; i < this.length; i++) { // sum += this[i]; // } // return sum; // } // } var arr = [1, 2, 3]; console.log(arr.sum()); console.log(Array.prototype); var arr1 = new Array(11, 22, 33); console.log(arr1.sum());
ES6之前并没提供 extends 继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。
fun.call(thisArg, arg1, arg2, ...)
// call 方法
function fn(x, y) {
console.log('我想喝手磨咖啡');
console.log(this);
console.log(x + y);
}
var o = {
name: 'andy'
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。