zl程序教程

您现在的位置是:首页 >  前端

当前栏目

JavaScript 面向对象与原型详解编程语言

JavaScript编程语言 详解 面向对象 原型
2023-06-13 09:11:47 时间

 使用构造函数与工厂模式不同之处:
(1).构造函数方法没有显示的创建对象(new Object);
(2).直接将属性和方法赋值给this对象;
(3).没有return语句;1 // 构造函数规范:
(1).函数名(function Box)和实例化构造名(new Box)相同且大写;
(2).通过构造函数创建实例对象,必须使用new运算符;


 构造函数的问题:
使用构造函数创建每个实例的时候,构造函数里的方法都要在每个实例上重新创建一遍;
因为ECMAScript中的函数是对象,因此每定义一个函数,也就是实例化了一个对象;
以这种方式创建函数,会导致不同的作用域链和标识符解析;

 

二 原型
// 我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象;

// 用途:包含可以由特定类型的所有实例共享的属性和方法;

// 理解:prototype是通过调用构造函数创建的那个对象的原型对象;

// 使用原型的好处是可以让所有对象实例共享它所包含的属性和方法;

// 也就是说,不必在构造函数中定义对象信息(属性/方法),而是可以直接将这些信息添加到原型中;

1.原型模式(prototype添加属性和方法)


// 1.__proto__:构造函数指向原型对象的一个指针;它的作用:指向构造函数的原型的属性constructor;
console.log(Box.prototype.isPrototypeOf(box)); 
// = true; 只要实例化对象,即都会指向;
// 虽然我们可以通过对象实例访问保存在原型中的值,但却不能访问通过对象实例重写原型中的值;

2.原型与in操作符

如何判断属性是在构造函数的实例里,还是在原型里? 可以用hasOwnProperty()函数来验证;
console.log(box.hasOwnProperty( name )); // 实例里若有返回true,否则返回false; 
in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在与实例中还是原型中;
console.log( name in box); // = true,存在实例中或原型中;3.更简单的原型语法(原型+字面量模式)

3.更简单的原型语法(原型+字面量模式)


// 但是,使用字面量创建的原型对象使用constructor属性不会指向实例,而是指向原型对象Object;构造函数的方式则相反;
 
// 而每创建一个函数,就会同时创建它的prototype,这个对象也会自动获取constructor属性;
 
// 重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;对象实例引用的仍然是最初的原型;

5.原生对象的原型

// 原型对象不仅仅可以在自定义对象的情况下使用,而是ECMAScript内置的引用类型都可以使用这种方式,
// 并且内置的引用类型本身也是用了原型;
console.log(Array.prototype.sort); // = function sort() { [native code] };
console.log(String.prototype.substring); // = function substring() { [native code] };

6.原型对象的问题


// 原型模式创建对象缺点:省略了构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的;
 
// PS:这种混合模式很好的解决了传参和引用共享的大难题;是创建对象比较好的方法;
// PS:使用动态原型模式,要注意一点,不可以再使用字面量的方式重写原型,因为会切断实例和新原型之间的联系;
Box(); 
// 通过创建Box实例,并赋值给Desk.prototype实现的;通过原型,形成链条; 
 
// 为了确保Box构造函数不会重写子类型的属性,可以在超类型构造函数后,再添加应该在子类型中定义的属性;

4.组合继承(原型链+借用构造函数)
// 借用构造函数虽然解决了引用共享和给超类型无法传参问题,但是没有使用原型,复用则无从谈起;所以需要组合继承模式;


,age); 
// 继承属性; 对象冒充; 将Box对象的作用域扩充到Desk中,Desk就会继承Box里的属性和方法;
// 超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部;


1.创建对象

对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体;
在没有类的情况下,可以采用下列模式创建对象;
(1).工厂模式:使用简单的函数创建对象,为对象添加属性和方法,然后返回对象;
这个模式后来被构造函数模式所取代;
(2).构造函数模式:可以自定义引用类型,可以像创建内置对象实例一眼使用new操作符;
缺点:它的每个成员都无法得到复用,包括函数;由于函数可以不局限于任何对象,因此没有理由不在多个对象间共享函数;
(3).原型模式:使用函数的prototype属性来指定那些应该共享的属性和方法;
组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,使用原型定义共享的属性和方法;

 

2.原型链

原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的;
子类型可以访问到超类型的所有属性和方法;
原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜单独使用;
解决方案:借用构造函数,即在子类型构造函数的内部调用超类型构造函数;
这样就可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数来定义类型;
使用最多的继承模式是组合继承;它使用原型链继承共享的属性和方法,而通过借用构造函数继承实例属性;

3.继承模式

(1).原型式继承:可以在不必预先定义构造函数的情况下实现继承;其本质是执行对给定对象的浅复制;
而复制得到的副本开可以得到进一步改造;
(2).寄生式继承:基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象;
为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用;
(3).寄生组合式继承:集寄生式继承和组合式继承的有点于一身,是实现基于类型继承的最有效方式;

 

 

http://www.jb51.net/article/63876.htm

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/17363.html

c