构造函数和原型

68 阅读3分钟

ES6之前,没有类的概念,是通过构造函数这种特殊函数构造对象

构造函数的问题:存在浪费内存的问题

function Star(uname, age){    this.uname = uname;    this.age = age;    this.sing = function(){        console.log('唱歌');    }}​var ldh = new Star('刘德华',18);
**构造函数的问题:存在浪费内存的问题**

解决方法:构造函数原型 prototype
公共属性放在构造函数里,公共方法放在原型对象上

构造函数原型 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', })