对于原型链的理解

这里首先说明下js中new关键字的作用

1.创建一个新的空对象。
2.将该对象的 __proto__ 指向构造函数的prototype(原型对象)。
3.将构造函数内的 this 指向新创建的对象。
4.执行构造函数内的代码,为对象添加属性和方法。
5.返回新创建的对象。
1.同一个构造函数的多个实例之间 无法共享属性(创建多个实例的时候会造成资源浪费)
function Cat(name, color) {
	this.name = name;
	this.color = color;
	this.meow = function () {
		console.log('miao');
	};
}

var cat1 = new Cat('LH', 'White');
var cat2 = new Cat('EH', 'Black');

cat1.meow === cat2.meow
// false

上面代码中,cat1和cat2是同一个构造函数的两个实例都具有meow方法
由于meow方法是生成在每个实例对象上面,所以两个实例就生成了两次
也即每新建一个实例就会新建一个meow方法
这既没有必要,又浪费系统资源,因为所有meow方法都是同样的行为,完全应该共享
这种缺点的解决方法即是JS的原型对象(prototype)

2.prototype

JS继承机制的设计思想是原型对象的所有属性和方法,都能被实例对象共享
上述缺点的解决方法理由: 也即若属性和方法定义在原型上则所有的实例对象都可以共享,从而节省内存并且体现出实例对象之间的联系

下面是为对象指定原型
JS规定每个函数都有一个prototype属性用于指向一个对象

function f() {}
typeof f.prototype // "object"

上面代码中,函数f默认具有prototype属性,指向一个对象
对于普通函数来说,该属性基本无用
但是对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型

function Animal(name) {
	this.name = name;
}
Animal.prototype.color = 'white';

var cat1 = new Animal('LH');
var cat2 = new Animal('EH');

cat1.color // 'white'
cat2.color // 'white'

上面代码中构造函数Animal的prototype属性,就是实例对象cat1和cat2的原型对象
原型对象上添加一个color属性则实例对象都共享该属性

原型对象的属性不是实例对象自身的属性
只要修改原型对象,变动就立刻会体现在所有实例对象上,当实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法(否则直接使用本身的属性和方法)
如:

cat1.color = 'black';
Animal.prototype.color = 'yellow';

cat1.color // "black"
cat2.color // "yellow"

总结一下原型对象的作用,定义所有实例对象共享的属性和方法

3.prototype的constructor属性

prototype对象有constructor属性默认指向prototype对象所在的构造函数,由于constructor属性定义在prototype对象上面,意味着可以被所有实例对象继承

function P() {}
var p1 = new P();

p1.constructor === P // true  constructor属性的作用:可以得知某个实例对象,到底是哪一个构造函数产生的
p1.constructor === P.prototype.constructor // true
p1.hasOwnProperty('constructor') // false   继承的所以是false,本身没有这个属性

由于constructor属性我们可以从一个实例对象新建另一个实例

function Constr() {}
var x = new Constr();

var y = new x.constructor();
y instanceof Constr // true

constructor属性表示原型对象与构造函数之间的关联关系
如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错

function Person(name) {
	this.name = name;
}

Person.prototype.constructor === Person // true

Person.prototype = {
	method: function () {}
};

Person.prototype.constructor === Person // false
Person.prototype.constructor === Object // true

如果不能确定constructor属性是什么函数,还有一个办法:通过name属性,从实例得到构造函数的名称

funciton Foo() {};
var f = new Foo();
f.constructor.name // "Foo"

4.__proto__属性

简单记就是:构造函数的原型对象prototype会等于实例对象的__proto__属性

var A = function (){}
var a = new A()
console.log(a.__proto__ === A.prototype) // true

5.模块化思想-封装私有变量(不暴露私有变量)

使用IIFE(Immediately-Invoked Function Expression)
将相关属性和方法封装在一个函数作用域中从而不暴露私有成员

var module1 = (function ($) {
	var _count = 0;
	var m1 = function () {
		// some code
	};
	var m2 = function () {
		// some code
	};
	return {
		m1: m1,
		m2: m2
	};
})(jQuery);

使用上面的方法外部代码无法读取内部的_count变量,上面的module1就是 JavaScript 模块化的基本写法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值