Javascript面向对象(五)——内置原型
来源:互联网 发布:国家数据恢复中心费用 编辑:程序博客网 时间:2024/03/29 16:48
Javascript面向对象(五)——内置原型
“prototype”属性在javascript内核中也应用广泛,所有的内置构造函数都用。我们首先看看简单的对象如何使用,然后进一步说明复杂对象。
Object.prototype
我们看看空对象输出什么?
let obj = {};alert( obj ); // "[object Object]" ?
代码生成的字符串 “[object Object]” 从哪来的,这是内置toString的方法输出,但他在哪,obj对象是空的。
实际上,简化写法 obj = {} 与 obj = new Object()
一样, 这Object()是内置对象构造函数,并且其有Object.prototype属性引用一个巨大的对象,包含toString和其他函数。
如下图(这些都是内置的)
当调用new Object()
,或者通过文本{…}方式创建对象时,[[Prototype]]也根据规则被设置为Object.prototype,上节我们讨论过。
然后,当调用obj.toString()时,其来自Object.prototype.我们可以用代码检查:
let obj = {};
alert(obj.__proto__ === Object.prototype); // true// obj.toString === obj.__proto__toString == Object.prototype.toString
注意,没有另外[[Prototype]]在Object.prototype链之上:
alert(Object.prototype.proto); // null
其他的内置原型
其他的内置对象如Array,Date,Function等也都有原型里的方法。
例如,我们创建数组[1,2,3]时,缺省内部调用new Array()
构造函数。所以数组数据被写进新对象中,并且Array.prototype作为它的原型,提供方法,这样节约内存。
根据规范,所有内置原型的顶端是Object.prototype,有时人们常说所有对象都从Object继承。
这里是一个全局(包括三个内置对象)图示:
让我们手工检查它们的原型:
let arr = [1, 2, 3];// it inherits from Array.prototype?alert( arr.__proto__ === Array.prototype ); // true// then from Object.prototype?alert( arr.__proto__.__proto__ === Object.prototype ); // true// and null on the top.alert( arr.__proto__.__proto__.__proto__ ); // null
一些原型中的方法可能重叠,举例,Array.prototype有自己的toString,输出逗号分隔每个元素。
let arr = [1, 2, 3]
alert(arr); // 1,2,3 <– the result of Array.prototype.toString
如我们之前所见,Object.prototype也有toString方法,但是Array.prototype在原型链中更近,所以数组的方法被使用。
如Chrome浏览器中,也可以展示层次结构(可能需要为内置对象输入console.dir)
其他内置对象也一样,甚至函数,它们是内置Function的构造器,方法如:call/apply等来自Function.prototype.Functions也有自己的toString方法。
function f() {}alert(f.__proto__ == Function.prototype); // truealert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects
基础类型
string,number和boolean情况更复杂。
我们知道他们不是对象,但如果我们访问他们的属性,那么临时的包装对象通过内置构造器(String、Number、Boolean)被创建,他们提供方法,然后销毁,
这些对象创建对我们来说是看不见的,大多数引擎对此做了优化未必如此,但是规范描述是这种方式。
这些对象的方法驻留在prototype中,如:String.prototype,Number.prototype和Boolean.prototype.
* 值null和underfined没有包装对象*
特定值null 和 undefined不同,他们没有包装对象。所以方法和属性对他们无效,也没有相应的原型。
改变内置原型
内置原型可以修改,例如,如果我们增加方法至String.prototype,则会对所有String有效:
String.prototype.show = function() { alert(this);};"BOOM!".show(); // BOOM!
在开发中,我们可以增加新的方法至内置原型中。增加他们至内置原型会有点诱惑,但通常这不是好主意。
原型是全局的,所以很容易冲突,如果两个库都增加了String.prototype.show
方法,那么其中一个会覆盖另一个。
最新的javascript编程方式,只有一种情况修改内置原型被允许,填充,换言之,在javascript规范中有些方法,但javascript引擎还不支持(或任何那些我们想支持的),那么我们手工实现并填充至内置原型中。
示例如下:
if (!String.prototype.repeat) { // if there's no such method // add it to the prototype String.prototype.repeat = function(n) { // repeat the string n times // actually, the code should be more complex than that, // throw errors for negative values of "n" // the full algorithm is in the specification return new Array(n + 1).join(this); };}alert( "La".repeat(3) ); // LaLaLa
借用原型
因为Array.prototype原型中有join方法。我们可以直接调用,代码如下:
function showArgs() { alert( Array.prototype.join.call(arguments, " - ") );}
这更有效,避免创建额外的数组对象[].
总结
- 所有内置对象拥有相同的原型:
- 方法存储在原型中(Array.prototype, Object.prototype, Date.prototype 等)
- 对象自身仅仅存储数据(数组元素、对象属性、日期)
- 基本类型也存储方法在包装对象的原型中,Number.prototype, String.prototype, Boolean.prototype;undefined和null没有对应的包装对象。
- 内置原型可以被修改或填充新的方法。但是不建议改变它们。可能这种情况应该容许,当有新的标准,但javascript引擎还不支持他们。
- Javascript面向对象(五)——内置原型
- 《JavaScript》——面向对象之原型
- 《JavaScript》——面向对象之原型
- Javascript 面向对象原型
- JavaScript面向对象-原型
- javascript--面向对象(五)动态原型模式
- javascript内置对象(五)
- 【JavaScript】——剖析面向对象与原型(一)
- 【JavaScript基础知识】——面向对象和原型
- 【JavaScript】——面向对象之原型优化
- Javascript——面向对象与原型(操作指南)
- Javascript面向对象(三)——原型继承
- Javascript面向对象(四)——函数原型
- Javascript面向对象(六)——方法原型
- javascript面向对象——prototype属性(原型属性)
- JavaScript—内置对象
- JavaScript—内置对象
- JavaScript原型面向对象构造
- 从构造函数看线程安全
- rac taf配置
- 八、服务详解
- 关于linux克隆,网络配置问题
- JavaScript HTML DOM
- Javascript面向对象(五)——内置原型
- 自定义圆形图片,拖动、多点触控缩放,不超出边界
- 方差分析
- Android Studio Gradle环境变量配置
- ORB特征点
- 变形最短路 SCU 4444 training 3
- LINUX HTB队列规定用户指南
- 1014. 福尔摩斯的约会
- the diary of sleep jobs & fg command line in linux