原型对象和原型链
2018-06-24 01:42:21来源:未知 阅读 ()
一、内置一级构造函数Object(首字母大写)
1、普通函数和构造函数的特点
普通函数:
1)、不建议使用new关键字调用,否则就成为构造函数的调用了;
2)、可以用return语句返回值,默认返回值是undefined;
3)、函数内部不建议使用this关键字,函数里面的this指向window,添加在this身上的属性是全局属性;
4)、函数命名以驼峰方式,首字母小写;
5)、每个普通函数都有一个原型(prototype对象),原型对象包含一个指向构造函数的引用,也有一个__proto__指明的继承关系。
构造函数:
1)、用new关键字调用,否则就成为普通函数的调用了;
2)、函数内部可以使用this关键字
在构造函数内部,this指向的是构造出的新对象。用this定义的变量或函数/方法,就是实例变量或实例函数/方法。需要用实例才能访问到;
3)、不用return返回值,有默认的返回值,也就是当前实例
当然,我们也可以让构造函数像普通函数一样有返回值,但是返回值必须是引用类型对象,不能是值类型,如:null、undefined、boolean、number、string,否则这个返回值无效,依然返回构造的实例(this指向该实例)。例如可以返回{a: 'A', b: 'B'}等等;
4)、函数命名建议首字母大写,与普通函数区分开
不是强制性的,但是命名规范。
5)、每个构造函数都有一个原型(prototype对象),原型对象包含一个指向构造函数的引用,也有一个__proto__指明的继承关系。
注意:普通函数和构造函数是没有界限,不是由命名决定的,是由调用方式决定的(是否用new调用),命名只是区分,是规范,告诉我们改用什么方式去调用,以免混淆。
2、Object构造函数
Object instanceof Object // true Object instanceof Function // true typeof Object // 'function'
Object既是对象,也是函数,我们称这种对象为函数对象,是js内置的构造函数。所有的函数对象都有一个默认属性为prototype(原型),这个属性Object.prototype是一个对象,所以称为原型对象,它的属性集合有:
console.log(Object.prototype);// 输出如下: constructor:Object() __proto__: null hasOwnProperty __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf get __proto__ set __proto__
特别重要的三个属性:
1)、Object.prototype.constructor是指向当前内置函数对象的引用。如下:
Object.prototype.constructor === Object // true
2)、Object.prototype.__proto__存放的是继承关系,Object是一级函数对象,它没有继承与别的对象,所以它继承的是空对象null。如下:
Object.prototype.__proto__ === null // true
3)、hasOwnProperty判断对象的属性是否为原型中的属性。
二、内置二级构造函数Function(首字母大写)
Function instanceof Object // true Function instanceof Function // true typeof Function // 'function'
1、Function是内置构造函数,所以有一个默认属性为prototype,这个属性Function.prototype是一个对象,它的属性集合分别有:
constructor:Function()
__proto__: Object.prototype
// 继承Object的属性(方法)
__defineGetter__
__defineSetter__
__lookupSetter__
Function.prototype.constructor是指向当前内置函数对象的引用,看:
Function.prototype.constructor === Function // true
js内置二级构造函数对象还有:
Date、Array、String、Boolean、RegExp、Number
我们可以自定义的二级函数对象,如:
var Person = new Function(); // 也可以这样(这只是一种快捷方式): function Person() {} Person instanceof Object // true Person instanceof Function // true typeof Person // 'function'
还是那句话:所以的对象都是由函数创建的。
重点:
1、二级构造函数的原型对象都是继承一级函数对象Object的原型对象,请看它们的原型指向:
Function.prototype.__proto__ === Object.prototype // true Date.prototype.__proto__ === Object.prototype // true Array.prototype.__proto__ === Object.prototype // true String.prototype.__proto__ === Object.prototype // true Boolean.prototype.__proto__ === Object.prototype // true RegExp.prototype.__proto__ === Object.prototype // true Number.prototype.__proto__ === Object.prototype // true Person.prototype.__proto__ === Object.prototype // true
什么情况下产生继承关系呢?个人觉得用new运算符 + 构造函数才会产生继承关系,但是这些二级构造函数对象都是js内置的,他们有很多私有属性也是内置的。
2、二级内置构造函数继承了一级构造函数Object的prototype中的所有属性,同时二级构造函数也有自己的私有属性,是Object的原型中没有的,我们经常用到的比如:
a). Date的私有属性
getDate、getDay、getFullYear等等
b). String的私有属性
length、slice、concat、search等等
c). Array的私有属性
length、join、slice、splice等等
三、非内置函数对象(非内置函数对象的没有内置的私有属性)
1、常用的非内置函数对象,这种对象也称为实例,这些对象都是new + 构造函数创建的,存在继承关系
构造函数(函数对象),原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的引用,即constructor,而实例都包含一个指向它继承的原型对象的引用即__proto__。
1)、var obj = {};(new Object()) 2)、var arr = [];(new Array()) 3)、var Num = new Number(); 4)、var Str = new String();
2、非函数对象(实例)没有原型,也就是没有prototype属性,但是非函数对象(实例)也是由函数创建的。既然它是由函数创建的,我们肯定能找到创建它的函数,如下:
a). json对象
var obj = new Object();// 很明显可以看出有Object函数创建 obj.constructor === Object // true
b). 数组对象
var arr = new Array(); arr.constructor === Array // true
数组和对象还可以通过快捷方式创建,如:[]和{},实质上也是通过函数创建的,这种快捷方式叫做语法糖。请看:
var obj = {}; obj.constructor === Object // true var arr = []; arr.constructor === Array // true
总结:非函数对象都有constructor属性指向创建该对象的函数。进一步说明对象都是由函数创建的。
3、非函数对象的继承关系
1)、由2可以知道,非函数对象都是通过一级或者二级内置函数创建的,有contructor直接指向创建函数。那么他们的继承关系是怎样的呢,是否有__proto__直接指向它继承的对象?答案是当然有啦。在js中,只要你是一个对象,不是你继承别的对象就是别的对象继承你,我们叫这种通过原型对象继承属性的方式叫原型链。看:
a). json对象
var obj = {}; obj.__proto__ === Object.prototype // true Object.prototype.__proto__ === null // true // 这就是obj最长的原型链了 obj.__proto__.__proto__ === null // true
b). 数组对象
var arr = []; arr.__proto__ === Array.prototype // true Array.prototype.__proto__ === Object.prototype // true Object.prototype.__proto__ === null // true // 数组对象最长的原型链 arr.__proto__.__proto__.__proto__ === null // true
同理,其他非函数对象皆一样。
2)、看一下非函数对象是否真的继承了别的对象的属性(方法)
a). 数组对象
var str = [1, 2, 3, 'a', 'b', 'c']; str.slice(2, 5); // [3, "a", "b"]
结果很明显,我们经常用就不多举例了。
4、非函数对象的内置对象arguments
arguments只出现在函数中,伪数组,格式和数组一样:[1, 2, 3],用于接收函数的参数。由Object创建,如下:
function arg() { console.log(arguments instanceof Object); // true console.log(arguments.constructor === Object); // true console.log(arguments.__proto__ === Object.prototype); // true console.log(typeof arguments.slice); // undefined }
内置属性length,可以通过索引访问对应得值。它不是数组,不能用数组的方法。如:
arguments.slice(); // undefined
如何转化为数组,从而可以使用数组的所以方法?
// Array.prototype.slice.call(arguments); function arg() { var arguments = Array.prototype.slice.call(arguments); console.log(arguments instanceof Object); // true console.log(arguments.constructor === Object); // false console.log(arguments.__proto__ === Object.prototype); // false console.log(typeof arguments.slice); // 'function' }
四、一级构造函数对象Object原型中的属性hasOwnProperty
一级构造函数对象Object原型中的属性hasOwnProperty会被所有的函数对象或者非函数对象继承。
我们都知道对象是可以自定义属性,如何判断一个属性是自定义的还是内置的或者继承原型链中的呢?就看hasOwnProperty了本身了。
那么我们哪些地方会用到hasOwnProperty。
1、判断
var obj = { a: 'A', b: 'B' }; obj.hasOwnProperty('toString'); // false(继承的) obj.hasOwnProperty('a'); // true (对象本身的)
2、遍历
Object.prototype.newProperty = 'newPropertyValue'; var obj = { a: 'A', b: 'B' } for(var key in obj) { console.log(key + '==>' + obj[key]) } // 结果: // a==>A // b==>B // newProperty==>newPropertyValue 如何不遍历newProperty呢? for(var key in obj) { if(obj.hasOwnProperty(key)) { console.log(key + '==>' + obj[key]) } }
// 结果: // a==>A // b==>B
五、总结
1、对象的定义:若干属性(方法)的集合;
2、所有的函数都是对象,但是对象不一定是函数,既是对象又是函数的对象称为函数对象;
3、所有的函数对象都有一个默认属性为prototype,这个属性prototype是一个对象。其中有一个属性为constructor,这个属性是当前函数的引用;另外一个是__proto__属性,指明继承关系。
4、所有的非函数对象(实例)都有一个constructor属性,这个属性是一个存放着创建该对象的函数;同时也有__proto__属性,指明继承关系。
5、由第3、4点可以说明:所有的对象(函数对象和非函数对象)都是由函数创建的。
6、什么是原型对象?
每一个函数对象都有的一个prototype属性,这个属性是一个对象,叫原型对象。只有函数(对象)才有原型,才能被继承。
7、什么是原型链(也叫原型对象链)?
用来继承属性(方法)的一条(原型)对象链。
(js任何一个对象不是被继承就是继承别的对象,所以js对象总能找到一条属于它的用来继承属性(方法)的(原型)对象链。)
很多地方都参考了别的文章,但是都忘了出处,就不列举了......,有错欢迎指出!
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- javascript面向对象入门基础详细介绍 2020-03-29
- jquery遍历筛选数组的几种方法和遍历解析json对象 2020-02-29
- jQuery表单对象属性过滤选择器实例详解 2020-02-21
- Javascript调试console对象的小技巧 2020-02-20
- JavaScript创建对象的三种方法 2020-02-14
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash