1.构造函数创建对象
1.1规则
(1)构造函数----函数名的首字母要大写eg:Person
function Student(name, age, gender, no) { this.name1 = name; // 前者是新定义的属性名,后者是我们传进来的形参 //绑定属性 this.属性名=属性值(形参上的变量) //属性名和形参的变量可以一致也可以不一致 this.age1 = age; this.gender1 = gender; this.no1 = no; this.say1 = function () { console.log(this.name1 + 'is saying'); } } var si=new Student('张三','20岁','大一','男'); var s2=new Student('李四','22岁','大三','女'); var s3=new Student('王五','20岁','大一','女');
(2)函数内部的实现
函数内的属性和方法前面需要添加this,表示当前对象的属性和方法
构造函数中不需要return返回结果
(3)调用函数
var 实例对象= new 构造函数名()
1.2 new关键字调用构造函数时,函数内部做了什么事情?
(1)在函数内部创建一个空对象-----函数内没写,系统帮忙完成的
(2)让this指向这个空对象
(3)执行构造函数内部的代码,在对象上添加属性和方法
(4)把对象返回----函数内没写return,系统帮忙完成的
1.3总结
- 构造函数用于创建某一类对象,其首字母要大写。
- 构造函数要和 new 一起使用才有意义。
- 构造函数约定首字母大写。
- 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
- 构造函数中不需要 return 返回结果。
- 当我们创建对象的时候,必须用new 来调用构造函数。
2.混合模式创建对象
和构造函数创建对象很像,但混合模式创建对象比构造函数创建对象要好一点,以后应用会更多一点
继承-原型继承 --prototype
之前构造函数创建方法都是this.方法,现在我们使用混合函数创造方法都是把方法从对象里面拎出来,然后通过对象.prototype.方法名=function(){}来创建方法,相当于我们把方法放到了一个公共的区域,大家在调用方法时都是调用同一个方法。
<script> function Person(name, age) { this.name = name; this.gae = age; } Person.prototype.say = function () { console.log(this.name + 'is saying'); } Person.prototype.test = function () { console.log(this.name + 'is testing'); } var p1 = new Person('张武', 18); var p2 = new Person('李四', 20); p1.test(); p2.test(); // 这两个方法是同一个,相当于开发了同一个系统 </script>
- JavaScript 是面向对象的语言,但JavaScript不使用类。
- 在 JavaScript中,不会创建类,也不会通过类来创建对象(就像在其他面向对象的语言中那样)。
- JavaScript基于prototype, 而不是基于类(构造函数名)的。
3.JavaScript 继承---借助构造函数
继承就是查找属性和方法的一种机制,先从自身(自己的构造函数)来查,如果有就直接用,如果没有,再从它继承的构造函数中查,直到找到为止,如果一直找不到,方法会报错,属性输出undefined,此时只能继承父构造函数中的方法,而不能继承父构造函数原型上的方法,想要继承父构造函数上的继承方法需要使用原型链来继承。
继承者------子类 派生类
被继承者-----父类 超类 基类
继承父类的方法: 父构造函数.call(this,实参1,实参2)
括号内第一个参数是对象,不一定是this,后续可以进行更换。
Father.call(this, name, age,say) //Father.call 是调用了父构造函数 this对象 指向是儿子的实例对象 // name,age是传的实参,在父亲构造函数中借用name和age属性
继承父类的例子:
<script> //父类 function Father(name, age) { this.name = name; this.age = age; this.say = function () { console.log('saying'); } } //子类 function Son(name, age, no, xueli) { // 继承父亲中的属性和方法 Father.call(this, name, age,say) //Father.call 是调用了父构造函数 this对象 指向是儿子的实例对象 //name,age是传的实参,在父亲构造函数中借用name和age属性 this.no = no; this.xueli = xueli; this.test = function () { console.log('testing'); } } var s1=new Son('廉颇', '20', '1000','本科'); console.log(s1.name,s1.age,s1.no,s1.xueli); </script>
4.原型链
原型链就是在原型上查方法,是一种查找方法的查找机制。先从自己的原型去查找,如果有方法,就是用,如果没有就向继承的父级对象去查,然后一直沿着原型对象一直向上查,找到就使用,找不到就报错
原型里面大部分放的都是方法,构造函数里面放置基本的属性。
constructor:构造器属性,可以通过这个查找出该原型的构造器
4.1原型链实现方法继承
(1)方法一:子构造函数.prototype=new 父构造函数();
这个方法不太好用,让会儿子的原型上同时拥有了父亲的属性和方法。此时通过.pototype.constructor查找出来子构造函数的this指向为父构造函数。可以通过回指来解决这个问题:子构造函数.prototype.constructor=子构造函数;
(2) 方法二:子构造函数.prototype=Object.create(父构造函数.prototype);
5.完美的组合继承
就是借助构造函数然后加上原型链,从而形成完美的组合继承。
父构造函数名.call(this,实参一,实参二);
子构造函数名.prototype=Object.create(父构造函数名.prototype);
子构造函数名.prototype.constructor=子构造函数名;
6.call方法的使用
函数名.call方法是函数的内置方法。无参时和直接调用函数的作用一样。
function text1(){ console.log('aaa'); } text1(); text1.call();
有参数时:参数一是对象(必传)。参数二及后面是函数的实参,以逗号分割依次传递。