面向对象编程(Object Oriented Programming,OOP编程)是一种计算机编程架构,它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。
抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征
在面向对象编程中,是通过“类”来创建对象的,类相当于模具。根据传递的数据来创建对选哪个,并且可以重复的创建对象。
在ES6之前的JavaScript版本中,是没有类的概念的,不过可以利用构造函数来代替类进行创建对象。
在构造函数跟普通函数并没有太大区别,只是调用的时候需要通过new关键字来调用。构造函数中的this会指向创建出来的对象,并且具备隐式返回操作。
定义类一般要求首字母大写,所以定义构造函数也要求首字母大写。
function Foo(name) {
this.name = name;
this.sayName = function() { console.log(this.name)}
}
var obj = new Foo('hello');
obj.sayName(); //hello
var obj2 = new Foo('hi');
obj2.sayName(); //hi
实现对对象的复制操作
浅拷贝是指把对象复制一份,实现原理是使用for...in 遍历对象的属性,浅拷贝只复制一层属性,如果某个属性的值也是一个对象,根据引用类型的特征,这个值为这个对象的指针,复制的只是指向该对象的指针,所以对于包含多层应用类型的对象还是会相互影响
function copy() {
var result = {};
for(var attr in obj) {
result[attr] = obj[attr]
}
return result;
}
var obj = {name: 'hello'};
var obj2 = copy(obj);
obj2.name = 'hi'
console.log(obj.name) // hello
console.log(obj2.name) // hi
上述代码中,copy通过for..in遍历对象属性,obj中name是一个string,为基本数据类型,所以改变obj2.name不会影响到obj.name
但是像下面这种包含多层引用的对象使用浅拷贝不能进行完全复制
function copy() {
var result = {};
for(var attr in obj) {
result[attr] = obj[attr]
}
return result;
}
var obj = {
name: {
age: 20
}
}
var obj2 = copy(obj)
obj2.name.age = 30;
console.log(obj.name.age) //30
console.log(obj2.name.age) //30
对copy函数进行改造,使用递归的方式
function copy() {
var result = {};
for(var attr in obj) {
if (typeof obj[attr] == 'object') {
result[attr] = copy(obj[attr])
}
else {
result[attr] = obj[attr]
}
}
return result;
}
原型 在构造函数下有一个prototype属性叫做原型,构造函数+ 原型整体也是一个对象,叫做原型对象,在原型对象下面可以添加属性和方法
共享 原型对象下的属性和方法,可供多个对象进行共享访问,这样就可以节省内存消耗。
原型链 那么为什么创建出来的对象可以访问到原型对象下面的属性和方法呢?这是通过原型链进行查找的。原型链即:连接对象与原型对象之间的纽带就是原型链。
原型链的最外层为Object.prototype,可通过控制台进行查看
function Foo(name) {
this.name = name;
}
Foo.prototype.sayName = function() { console.log(this.name)
}
var obj = new Foo('hello');
var obj = new Foo('hi');
// __proto__: 内部属性:查找当前对象的原型对象
console.log(obj.__proto__ == Foo.prototype) // true
在JavaScript中提供了很多跟面向对象相关的语法,这些语法可以辅助我们进行面向对象开发。
constructor 原型对象下唯一默认自带的属性,用于查看对象的构造函数。
instanceof 左边是实例对象,右边是构造函数。它会检查右边的构造函数的原型对象是否在左边对象的原型链上。
in与for...in in运算符返回一个布尔值,表示一个对象是否具有某个属性。for...in循环可获得对象的所有可枚举属性。
function Foo() {
this.name = 'Lee'
}
// Foo.prototype.constructor = Foo;
/*
如果采用下面这种定义多个prototype的时候需
要绑定constructor,因为这个新
对象的constructor指向的是Object,不手动绑定的话可能会有意想不到的结果
*/
Foo.prototype = {
constructor: Foo,
sayName: function() { console.log(this.name)}
}
var obj = new Foo();
console.log(obj.constructor) // Foo
console.log(obj instanceof Foo); // true
console.log('name' in obj) // true
原文:https://www.cnblogs.com/dobeco/p/11755657.html