面向对象
- 创建对象在内存中是怎么样表示的?
创建对象的方法:- 字面量的方式创建
var obj={
userName:'icessun',
age:21
}
它省略了构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的(每个实例对象没有自己的特性)
-
new object
的方式创建
var obj =new Object();
obj.userName='icessun';
obj.showUserName=function(){
return obj.userName; // this.userName
}
alert(obj.userName + '--->'+obj.showUserName());
var obj2 =new Object();
obj2.userName='icessun2';
obj2.showUserName=function(){
return obj2.userName; // this.userName
}
alert(obj2.userName + '--->'+obj2.showUserName());
当然还有原型的方式创建对象,Object.creat()
方式创建对象。
简单工厂模式批量创建对象
当想创建多个对象的时候,可以使用函数封装起来,简单工厂模式就可以创建多个对象,减少代码的冗余。
// 在函数的内部使用new object的方式创建对象,然后返回这个对象
function CreatObj(uName){
var obj = new Object();
obj.userName = uName;
obj.showUserName = function(){
return obj.userName;
}
return obj;
}
// 第一个对象
var obj = CreatObj('icessun');
console.log(obj.showUserName()); // icessun
// 第二个对象
var obj2 = CreatObj('icessun1');
console.log(obj2.showUserName()); // icessun1
构造函数创建对象
使用构造函数创建对象,简化上面的代码;在函数前面使用new
调用,就叫做构造函数。
function CreatObj (uName){
// 也不需要手动new Object ,因为外面使用new的时候,就会在内存之中创建一个对象。
this.userName=uName;
this.showUserName=function(){
return this.userName;
}
// 函数为构造函数的时候,会自动return this出来 ;当然也可以把自己想return出来的属性return出来,就会把return this覆盖了
}
var obj =new CreatObj('icessun');
var obj2=new CreatObj('icessun1');
console.log(obj.showUserName());
console.log(obj2.showUserName());
console.log(obj2.showUserName === obj.showUserName) ;//false
构造函数的方法,new
一个对象,函数里面的this
指向的就是这个对象本身;故每创建一个对象,就在内存里面开辟一个空间,里面存储着这个对象上面的属性和方法;虽然在对象里面都有相同的方法,但是这些函数都是不相等的,函数在JS
里面是引用类型,引用的比较是看是否是同一块内存。由于每一个对象上面都有作用相同的方法,没有实现共用,造成内存浪费,我们可以使用原型对象来解决这个问题。
原型对象和隐式原型
把加在对象上面的方法,转移到构造函数的原型对象上面。
function CreatObj (uName){
this.userName=uName;
}
// 实现了不同对象使用同一个方法
CreatObj.prototype.showUserName=function(){
return this.userName;
} ;
var obj =new CreatObj('icessun');
var obj2=new CreatObj('icessun1');
console.log(obj.showUserName());
console.log(obj2.showUserName());
console.log(obj2.showUserName === obj.showUserName) ;// true
图解原型对象
原型prototype
性质:
- 每个对象上面都有一个原型属性
[[prototype]]
,这个[[prototype]]
会指向该对象的原型对象CreateObj.prototype
; - 每个对象的原型对象
CreateObj.prototype
默认都有一个coustructor
属性,指向该对象CreateObj
,对象所在的内存空间; - 每个对象都有一个隐式原型
__proto__
,指向创建该对象的原型对象CreateObj.prototype
上; - 每个对象的原型对象
CreateObj.prototype
上面也有隐式原型__proto__
当实例调用一个属性或者方法的时候,先在本身查找,如果本身上面没有,那么就顺着实例的隐式原型的指向,依次往上查找,有就返回,没有就继续;如果本身存在,就使用本身上的,停止查找。
原型对象`prototype的作用:
- 实现方法和属性在不同实例之间达到共享的目的。
3种引用类型
- 函数
用一个函数交互两个数的位置:
function swap(n1,n2){
var temp = null;
temp=n1;
n1=n2;
n2=temp;
}
var a=10,b=20;
swap(a,b);
console.log('a:'+a+',b:'+b); // a=10 b=20
使用上面的方法,你会发现其实位置根本就没有发生变化,那是因为在函数局部作用域的问题,函数执行完毕了,里面的变量就会销毁,所以其交互的值根本没有改变。
我们可以把交互的值返回出来,然后用变量去接收;也可以使用下面这个方法:
function swap(a,n1,n2){
var temp =null;
temp=a[n1];
a[n1]=a[2];
a[2]=temp;
}
var arr =[10,20];
swap(arr,0,1);
console.log(arr);// [20,10]
- 数组
var arr=[10,20,30];
var arr2=arr;
arr2.push(40);
console.log(arr); // [10,20,30,40]
console.log(arr2); // [10,20,30,40]
当碰到两个引用类型的数组进行=
操作,其实就是两个引用类型的变量指向同一个内存地址空间,也就是说共用一个内存单元。
怎么样把数组拷贝,使其不共用一个内存单元?
var arr=[10,20,30];
var arr2=[];
for(var i=0;i<arr.length;i++){
arr2[i]=arr[i];
}
arr2.push(40);
console.log(arr); // [10,20,30]
console.log(arr2); // [10,20,30,40]
- 对象
网友评论