JavaScript之面向对象
面向对象编程
JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现的。
let Student = { name: "robot", height: 1.2, run: function () { console.log(this.name + "is running"); } }; let s1 = { name: "小米" }; //原型链,所有对象都是实例 s1.__proto__=Student; console.log(s1.name); s1.run();
Object.create()
方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有。
function createStudent(name) { let s=Object.create(Student); s.name=name; return s; } let xiao=createStudent("xiao"); xiao.run() console.log(xiao.__proto__===Student); //true
创建对象
使用obj.xxx访问一个对象的属性是,引擎会现在该对象上查找,如果没找到,就会上溯一直到到Object.prototype对象,否则返回undefined
。
例如创建一个Array对象:arr ----> Array.prototype ----> Object.prototype ----> null
定义一个函数:arr ----> Array.prototype ----> Object.prototype ----> null
- 构造函数
function student(name) { this.name=name; this.hello=function () { alert("hello,"+this.name) } } //不用new时就是一个普通函数,返回undefined,使用new时,就变成一个构造函数 //this指向新创建的对象,并默认返回this var xiaoming = new Student('小明'); xiaoming.name; // '小明' xiaoming.hello(); // Hello, 小明!
原型链xiaoming ----> Student.prototype ----> Object.prototype ----> null
用new Student()
创建的对象还从原型上获得了一个constructor
属性,它指向函数Student
本身。xiaoming.constructor === Student.prototype.constructor; // true Student.prototype.constructor === Student; // true Object.getPrototypeOf(xiaoming) === Student.prototype; // true xiaoming instanceof Student; // true
上面的代码可以表示为:
xiaoming.hello === xiaohong.hello; // false
要让创建的对象共享一个hello函数,字需要把hello函数移动到兑现共同的原型上就行
function Student(name) { this.name = name; } Student.prototype.hello = function () { alert('Hello, ' + this.name + '!'); };
为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写。
原型继承
new PrimaryStudent() ----> PrimaryStudent.prototype ----> Student.prototype ----> Object.prototype ----> null
function inherits(Child, Parent) { var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; } function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototype.hello = function () { alert('Hello, ' + this.name + '!'); } function PrimaryStudent(props) { Student.call(this, props); this.grade = props.grade || 1; } // 实现原型继承链: inherits(PrimaryStudent, Student); // 绑定其他方法到PrimaryStudent原型: PrimaryStudent.prototype.getGrade = function () { return this.grade; };
class继承
class Student { constructor(name) { this.name = name; } hello() { alert('Hello, ' + this.name + '!'); } } class PrimaryStudent extends Student { constructor(name, grade) { super(name); // 记得用super调用父类的构造方法! this.grade = grade; } myGrade() { alert('I am at grade ' + this.grade); } }
推荐使用这种方式。