什么是面向对象?
面向对象是一种编程思想,是对现实世界理解和抽象的方法。
属性和方法
- 属性一定是在某个非空对象上的,只有非空对象才能加属性。
- 一般属性写在类上,方法写在类的原型上
var arr = [];
arr.num = 10;
arr.num++;
alert(arr.num);//11
空字符串不能设置属性
var str = '';
str.num = 10;
str.num++;
alert(str.num);//undefined
方法
function fn1(){
alert(this)
}
fn1();//window
var arr = [1,2,3];
arr.fn1 = function(){
alert(this)
}
arr.fn1();// 1,2,3
new云算符
new是专门运算函数的。
用了new之后,函数可以不加括号就调用,new运算之后的()主要是为了传参数用。
new之后在函数内默认创建一个空白的对象,如果return后面跟着对象类型或者一个函数,那么返回值就是return后面的值。若没有,那么函数的返回值就是new出来的这个对象。
什么是构造函数?
构造函数就是专门来构造一个对象的,也称作工厂函数。
function Animal(name,age,food) {
//原材料 默认创建的,可以省略
var json = {};
//加工
this.name = name;
this.age = age;
this.food = food;
//出厂 默认返回new出的对象
return json;
}
//类的实例化过程 taidi就是实例化对象
var taidi = new Animal('泰迪',4,'狗粮');
原型
当一个函数被声明的时候,这个函数下有一个默认的属性prototype,这个属性的值是一个对象,当我们调用一个对象的属性或者方法时,若该对象自身并没有这个属性或者方法,那么就会调用这个对象的构造函数下的prototype下面的属性或者方法。prototype是给这个类的实例化对象使用的,自身并不能使用。
原型链
对象有原型链(对象与构造函数原型的桥梁)
函数有原型
碰到对象的时候找原型链,碰到函数找原型,原型只给这个类的实例化对象使用。
原型与原型链的查找方法
如果是对象
先找原型链 -> 构造函数的原型 -> 构造函数的原型链 -> 对象的原型
如果是找函数
会先找原型链(因为函数的原型是给这个函数的实例化对象使用的)-> 构造函数的原型
1.这个函数就是Function -> Function.prototype -> Function.prototype.__proto__ -> Object.prototype
2.Array.__proto__ -> Function.prototype -> Function.prototype.__proto__ -> Object.prototype
包装对象
当我们尝试去查看某一个简单类型的属性或者方法的时候,系统会偷偷的将这个简单类型转成对象类型,我们通过这个对象去查看属性或者方法。查看完之后,这个对象会被自动销毁。这个过程就是简单类型也能查看属性火或者方法的原理。
简单类型的属性只能读,不能写。
当使用原始类型(string、number、boolean)的属性或方法的时候,内部会自动的转换成对象类型。所创建的这个对象就是包装对象。
包装对象的特点
当常见这个对象后,可以调用属性或者方法,使用后立即销毁,所以不能给简单类型添加属性或者方法。
hasOwnProperty
查看某一个属性是不是这个对象自身的。
注意: 一定是在当前这个对象中,并不会沿着原型链查找属性,它只会查找自身的属性。
function Animal(name,age){
this.name = name;
this.age = age;
}
var taidi = new Animial('泰迪',2);
console.log(taidi.hasOwnProperty('name'); //true name是Animal的自身属性。
function Animal2(name,age){
this.age = age;
}
Animal2.prototype.name = '泰迪2';
var dog2 = new Animal2('泰迪2',2);
console.log(dog2.hasOwnProperty('name'));// false name 不是Animal2的属性
Object.prototype.food = function() {
console.log('骨头');
};
dog.food();//虽然food能调用到,但不是Animal自身的属性
for in
简单类型赋值就是赋值,不会影响另一个数据。
对象的赋值是赋址,都会引用一个内存地址。
var num = 10;
var num2 = num;
num2++;
console.log(num2); // 11
console.log(num); // 10
var obj={
'name':'javascript',
'age':29
}
var obj2 = {};
for(var attr in obj){
obj2[attr] = obj[attr]
}
obj2.name = 'html';
console.log(obj.name); // javascrip
console.log(obj2.name); // html
深度克隆
var arr = [1,2,3,[1,2],function(){},{'name':'javascript'}]
var arr2 = extend(arr);
function extend(obj) {
var o = obj.push?[]:{};
for(var attr in obj){
if(typeof obj[attr] === 'object'){
o[attr] = extend(obj[attr]);
}else{
o[attr] = obj[attr];
}
}
return o;
}
arr2[3].push(9);
console.log(arr2[3]);// 1,2,9
console.log(arr[3]);// 1,2
字符串对象格式互转
json.stringify(obj) 对象转成字符串
三个参数:对象,回调函数,调整格式缩进量
var arr = [1,2,3];
var str = JSON.stringify(arr);
console.log(str);//[1,2,3]
var json = {
'name':'javascript',
'age':29
}
console.log(JSON.stringify(json,function(key,val){
if(key === 'name'){
return val.replace(/j/,'J');
}
return val;
},2))
- 字符串转成对象
var json = '{"name":"javascript","age":29}';
console.log(JSON.parse(json,function(key,val){
if(key === 'name'){
return 'html';
}
return val;
}));
var json2 = eval('('+json+')');
console.log(json2);//eval 这种方法并不推荐使用(有安全隐患,容易注入病毒)
constructor
可以查看某个对象的构造函数是谁
obj.constructor == Objcet
注意:
constructor会无形被修改,虽然不会改变某个方法的执行结果,但是会影响你的客户维护。
解决:
手动修改constructor指向
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.portotype = {
constructor:Animal; //手动改变constructor的指向
say:function(){
alert(this.name);
}
}
var a = new Animal('泰迪',2);
console.log(a.constructor == Animal); //true
var arr = [];
console.log(arr.constructor == Array);//true
var string ='';
console.log(string.constructor == String);//true
instanceof
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
语法:obj instanceof Objcet 如果是就true否则为false
call
当某个函数声明的时候系统就默认的给这个函数加了一些属性或者方法,其中就有call
有两个参数
第一个:改变this指向。写什么this就是什么
第二个及以后的参数为实参(有几个形参就写对应的实参)
apply
同样能改变this的指向
有两个参数
第一个参数改变this指向
第二个参数为数组,是实参的集合,有几个形参就在数组中写几个对应的实参。
toString
将某种数据类型转成字符串,内置对象都有toString方法。使用alert的时候,系统会自动调用该数据类型的toString.
内置对象有Array,String,Object。
toString可以对数字进行进制转换,默认是十进制。
var num = 10;
console.log(num.toString(16));
//不使用alert(),查看数据类型
var str = '';
var fn = function(){};
var tS = Object.prototype.toString;
console.log(tS.call(num));
console.log(tS.call(str));
console.log(tS.call(fn));
var aEle = document.getElementsByTagName('*');
var A = Array.prototype.slice;
var arr = A.call(aEle);
arr.forEach(function(item,i){
item.className = 'A';
})
console.log(tS.call(arr));