< script>
// 1.创建类class 创建 一个明星类
class Star {
//类的共有属性放到constructor里面
constructor(uname, age) {
this.uname = uname ;
this.age = age;
}
//我们类里面所有的函数不需要写function,多个函数方法之间不需要添加逗号分隔
sing () {
console.log('我会唱歌')
}
}
// 2.利用类创建对象new
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友',20);
console . log(1dh);
console. log(zxy);
</script>
class Father { } // 父类
class Son extends Father { } // 子类继承父类
class Father {
say() {
return ' 我是爸爸';
}
}
class Son extends Father {
say() {
console.1og(我是儿子);
}
}
var son = new Son ();
son.say();
class Person { // 父类
constructor ( surname) {
this. surname = surname;
}
}
class Student extends Person {
//子类继承父类
constructor (surname, firstname) {
super (surnane) ;
// 调用父类的constructor (surname)
this.firstname = surname; //定义子类独有的属性
}
}
三个注意点:
1. 概念
在ES6之前,对象不是基于类创建的,而是用种称为构建函数的特殊函数来定义对象和它们的特征。
创建对象可以通过以下种方式:
2. 构造函数
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new 一起使用。我
们可以把对象中一些公共的属性和方法抽取出来 ,然后封装到这个函数里面。
new在执行时会做四件事情:
①在内存中创建一个新的空对象。
②让this指向这个新的对象。
③执行构造函数里面的代码,给这个新对象添加属性和方法。
④返回这个新对象(所以构造函数里面不需要return ) 。
// 利用构造函数创建对象
function Star(uname, age) {
this. uname = uname ;
this.age = age;
this.sing = function() {
console.log( '我会唱歌' );
}
}
var 1dh = new Star('刘德华’,18);
var zxy = new Star('张学友',19);
console .1og(1dh);
1dh.sing();
zxy.sing();
// 1. 实例成员就是构造函数内部通过this添加的成员uname age sing 就是实例成员,实例成员只能通过实例化的对象来访问
console . log(1dh. uname);
ldh. sing();
console. log(Star .uname); //不可以通过构造函数来访问实例成员
// 2.静态成员在构造函数本身上添加的成员 sex 就是静态成员
Star.sex = '男';
console . log(Star.sex); // 静态成员只能通过构造函数来访问
console.1og(1dh.sex); // 不能通过对象来访问
3. 构造函数的问题
构造函数方法很好用,但是存在浪费内存的问题。
4. 构造函数原型prototype
5. 对象原型_ proto_
6. constructor构造函数
function Star(uname, age) {
this. uname = uname ;
this.age = age;
//很多情况下,我们需要手动的利用constructor这个属性指回原来的构造函数
// Star . prototype. sing = function() {
// console. log( '我会唱歌' );
// };
// Star . prototype. movie = function() {
// console . log('我会演电影');
// }
// 如果我们修改了原来的原型对象,给原型对象赋值的是个对象,则必须手动的利用 constructor指回原来的构造函数
Star. prototype = {
constructor: Star,
sing: function() {
console.1og(我会唱歌' );
},
movie: function() {
console.log( '我会演电影');
}
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
console .1og(Star. prototype);
console .1og(1dh._ proto__ ) ;
9. JavaScript的成员查找机制(规则)
①当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
②如果没有就查找它的原型(也就是_ proto_ 指向的prototype原型对象)。
③如果还没有就查找原型对象的原型( Object的原型对象)。
④依此类推一直找到Object为止( null )。
⑤_ proto 对象原型的意义就在于为对象成员查找机制提供一 个向,或者说一条路线。
10. 扩展内置对象
可以通过原型对象,对原来的内置对象进行扩展自定义的方法。比如给数组增加自定义求偶数和的功能。
<script>
//原型对象的应用:扩展内置对象方法
console.log(Array. prototype);
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
var arr=[1,2,3];
console.log(arr.sum());
</script>
1. 概念
ES6之前并没有给我们提供extends继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。
2. 借用构造函数继承父类型属性
核心原理:通过call()把父类型的this指向子类型的this ,这样就可以实现子类型继承父类型的属性。
<script>
// call方法
function fn(x, y) {
console.1og( '我想喝手磨咖啡);
console . log(this);
console.1og(x + y);
}
var obj = { name: 'lfl' }
// 1. cal1() 可以调用函数
// fn. call();
// 2. call() 可以改变这个函数的this指向此时这个函数的this就指向了o这个对象
fn.call(obj, 1, 2);
</script>
<script>
//借用父构造函数继承属性
// 1.父构造函数
function Father(uname, age) {
// this指向父构造函数的对象实例
this .uname = uname;
this.age = age;
}
// 2.子构造函数
function Son(uname, age, score) {
// this指向子构造函数的对象实例
Father . call(this, uname, age);
this.score = score;
}
var son = new Son ('刘德华',18, 100);
console . log(son);
</script>
3. 借用原型对象继承父类型方法
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father . call(this, uname, age);
this. score = score;
}
// Son. prototype = Father . prototype;这样 直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Son.prototype = new Father ();
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son . prototype . constructor = Son;
//这个是子构造函数专门的方法
Son. prototype.exam = function() {
console.1og('孩子要考试');
}
var son = new Son('刘德华',18, 100);
console. log(son);
console . log(Father .prototype);
console . log(Son. prototype . constructor);