面向对象编程是一种设计思想,它是现实世界的抽象,任何现实世界中的事物都可以用面向对象思想来解决。“万物皆对象”,JavaScript中不是面向对象编程。而是面向函数编程,这里,JavaScript中函数是“一等公民”,那什么又是“一等公民”呢?就是函数和整数、字符串等常见概念的地位是平等的,一个整数和一个字符串等对象可以干的事,一个函数也可以办到。
面向对象我们经常和面向过程做比较,面向过程是C语言编程的核心思想
- 面向对象注重于抽象事物,而面向过程注重于描述事物
- 面向对象逻辑清晰有条理,而面向过程比较方面 JS通过函数和原型,模拟了传统的
- 面向对象编程中类的概念,实现了面向对象的编程模式
面向对象核心:封装、继承、多态
创建对象的三种方式:
1、创建对象
var objA={
name:"A",
eat:function(){}
}
var objB={
name:"B",
eat:function(){}
}
var objC={
name:"C",
eat:function(){}
}
2、工厂模式
function createObj(name){
var obj={};
obj.name=name;
obj.eat=function(){
console.log(name+"eat");
}
return obj;
}
3、构造函数模式
function CreateObj(name){
this.name=name;
this.eat=function(){
console.log(this.name+"eat");
}
}
- 在函数执行的时候,会在函数内部创建两个对象,arguments,this
- arguments存储着实参的一个类数组对象
- this指向函数的上下文(谁调用这个函数,this就指向谁)
什么是类数组
原文链接:添加链接描述
- 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理);
- 不具有数组所具有的方法;
var arr=[1,2,1,4,32,2,323,23,32,32,33]数组
类数组:var arrLike={0:"chen",1:"xin",2:"hui",length:3}
像这种有length属性,key以数字标识的就是类数组
类数组转换为数组
args = Array.prototype.slice.call(arguments);
Array.prototype.slice=function(){
var result = new Array();
start = start || 0;
end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键
for(var i = start; i < end; i++){
result.push(this[i]);
}
return result;
}
call和apply动态改变this指向
var objA={
name:"A",
eat:function(){},
A:bbb,
B:{
C:bbb
}
}
function bbb(){
console.log(this);
console.log(arguments)
}
bbb();//window
objA.A();//objA
objA.B.C();//objA.B
//通过call改变指向
bbb.call(objA,1,2,3,3,32,32,323,);//objA
objA.A.call(objA.B,323,23,,2,323,23,32,3);//objA.B
objA.B.C.call(objA.B,3223,23,2,32,33,23,);//objA.B
//通过apply改变指向
bbb.call(objA,[1,2,3,3,32,32,323]);//objA
objA.A.call(objA.B,[323,23,,2,323,23,32,3]);//objA.B
objA.B.C.call(objA.B,[3223,23,2,32,33,23]);//objA.B
new做了那些事?
- 创建一个新空对象
- 将构造函数的propertype属性指向新对象的__proto__
- 将构造的this指向空对象
- 执行构造函数的代码
- 将新对象返回
function BBB(){
console.log(this)
}
(function(){
var obj={};
obj.__proto__=BBB.prototype;
BBB.call(obj);
return obj
})
在声明函数的时候,会自动创建一个prototype属性,我们管它叫做原型,一般用来存放实例公用的方法。
在函数访问属性的时候,会在当前对象中寻找,如果当前对象中没有,则向该对象的__proto__属性中去寻找,如果还没有,则一直向下寻找,直到null为止