ES6之前,没有类的概念,是通过构造函数这种特殊函数构造对象
构造函数的问题:存在浪费内存的问题
function Star(uname, age){ this.uname = uname; this.age = age; this.sing = function(){ console.log('唱歌'); }}var ldh = new Star('刘德华',18);
构造函数原型 prototype
构造函数通过原型分配的函数是所有对象共享的,就不会再需要每个对象去新开辟一个内存空间存放函数
JavaScript规定,每个构造函数都有一个prototype属性,指向另一个对象。注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有 我们一般把那些不变的方法,直接定义在prototype对象上,这样所有的对象实例就可以共享这些方法了
原型是什么? 一个对象,也称prototype为原型对象 原型的作用是什么? 共享方法,解决构造函数浪费内存的缺点
<script> //给数组加一个求和方法 Array.prototype.jiafa = function() { console.log('自定义的加法'); var sum = 0; for (var i = 0; i < this.length; i++) { sum += this[i]; } console.log(sum); } var a = [1, 2, 3]; a.jiafa(); </script>
对象原型: proto
function Star(uname, age) { this.uname = uname; this.age = age;}Star.prototype.sing = function(){ //单个方法 console.log('唱歌');}Star.prototype = { //当有多个方法,这样使用 constructor:Star, //关键要指回原构造函数,否则会覆盖掉 dance: function(){ console.log('跳舞'); }, movie:function(){ console.log('电影'); }}var ldh = new Star('刘德华',18);star.sing();console.log(ldh.__proto__ === Star.prototype) //true方法查找:首先看对象身上是否有该方法,如果有就执行这个对象上的方法如果没有,通过对象上的__proto__去构造函数原型对象prototype身上去查找该方法
为什么ldh能够使用原型的sing函数呢? 因为ldh这个对象身上也有一个对象原型proto,这个proto指向构造函数原型对象prototype,也就能使用sing了
constructor 构造函数
prototype和__ proto __ 都有一个constructor属性,指向原来的构造函数,说明这是属于哪个构造函数的
继承call():ES6之前没有extends继承,可以通过构造函数+原型对象模拟继承,称为组合继承
call() 调用这个函数,并且可以修改这个函数里this的指向
call(thisobject, o1,o2.....) 第一个参数是指修改this指向的参数,其余参数就是当做原来函数的普通参数使用
function fn(){ console.log('咖啡'); console.log(this); //原来指向window}
var p = { name : 'jason'}fn(); //调用fn.call(); //调用fn.call(p); //this指向了p
组合继承:
function Father(uname, age){ //this指向父构造函数的实例对象 this.uname = uname; this.age = age;}Father.prototype.money = function(){ console.log('money');}function Son(uname, age){ //this指向子构造函数的实例对象 Father.call(this,uname,age);//将this指向子类的实例对象}导致修改//son想要继承father的money方法//Son.prototype = Father.prototype; //这种方法会有问题,son.prototype指向了Father.prototype,导致修改son.prototype的话也会修改了Father.prototype,比如son增加一个emit方法,那么father也会有这个方法//正确的做法Son.prototype = new Father(); //实例化对象,Father的对象也能使用money方法,修改son.prototype的话也不会修改Father.prototypeSon.prototype.emit = function() { console.log('考试');}var son = new Son('楼德华',18);son.money();
ES5中的新增方法
1.数组方法: 迭代(遍历方法):forEach,filter,map,some,every 字符串方法:trim() 去除字符串两侧的空白字符,不影响原字符串 对象方法: Object.keys()获取对象自身所有的属性,返回包含对象属性名的数组 Object.defineProperty(obj, prop, des)
obj:要操作的对象 prop:操作的属性名,如果obj中没有该属性名,就添加 des:描述
var arr = Object.keys(obj);
Object.defineProperty(obj,'name',{ value: 'jason', })