JS--oop高级部分

来源:互联网 发布:韩国第一淘宝模特短发 编辑:程序博客网 时间:2024/04/29 06:12

  原文代码链接在github上:
  js源码也是基于原型的程序,因此写面向对象的时候要小心不要修改源码。
  尽量不要修改或者添加系统对象下的属性。

arguments: 是实参的集合

包装对象:
     引出:字符串为什么也有方法呢?
     包装对象: 基本类型(String Number Bolllean )都有自己对应的包装对象。跟Array Date等构造函数一样;
     null underfined  没有
    
     var str = 'anikin';
     str,charAt(0) // 因为方法跟属性是跟着对象身上,但是str是基本类型,是如何挂载方法跟属性的呢?
    方法跟属性是挂载到了包装对象身上
    基本类型先会找到对应的包装对象类型,然后包装对象把所有的属性和方法都给了基本类型;包装对象消失;
        ===送快递
  
    var str = new String('Hello');
     String.prototype.charAt = function(){ 
     return this.charAt(this.length-1);
 }

var str = 'anikin';
str.number = 12; //创建一个包装对象,然后包装对象消失
alert( str.number ); // 再次重新创建一个包装对象,但是没有值,所以是underfined;因为没有在原型上创

原型链:实例对象与原型之间的链接
--proto__ 隐式链接:原型链的最外层是Object.prototype;
JS--oop高级部分 - 眷恋天空的驴 - 迷茫。。。。。
 
面向对象的一些方法和属性(平时开发用的不多,面试容易问)
- -hasOwnProperty(): 看是不是自身对象下面的属性  返回真假
    这个方法是加载原型链顶层的Object.prototypr.hasOwnProperty 上的。

var arr = [1,2,3];
arr.num = 3;
Array.prototype.num2 = 12;
alert( arr.hasOwnProperty('num') );
// true 是自己的私有属性
alert( arr.hasOwnProperty('num2') );
// false 在原型中,不是实例对象的属性


--constructor: 查看对象的构造函数 :返回的是一个构造函数,跟原型没关系
    --可以利用这属性做数组的判断:alert(arr.constructor ==Array) true
    --这个属性是for in 找不到的,JS源码的设计

var arr = [1,2];
alert(arr.constructor); // function Array(){}


function Person(){
}
Person.prototype.num = 12;
//Person.prototype.constructor = Array; //
可以手动修改指向
var p1 = new Person();
alert(p1.constructor); //
function Person(){}


唯一句JS自动生成的:function aa(){};
只要创建函数,JS源码会自动给我们创建:aa.prototypr.constructor = aa; 

原型其实也是对象,因此也可以写成json的格式:但是这样子会将constructor: 指向变成这个json,因此需要先修正以下指向,因为这样子成了赋值。

function Person(){
this.name = 'anikin';
this.age = 12;
this.nation = 'china';
this.sex = 1;
};
Person.prototype = {
constructor: Person, // Person(){} //
如果不加修正指向的话,是Object这个构造函数
showName: function(){
alert( this.name )
},
showAge: function(){
alert( this.age)
},
showNation: function(){
alert( this.nation)
},
showSex: function(){
alert( this.sex )
}
};

var p1 = new Person();
alert(p1.constructor);

一般大型的库jquery中面向对象的部分中,原型都是利用这种json的格式写的,所以要修改constructor的指向,不过一般开发中不会修改指向的。

instanceof: 运算符‘对象与构造函数在原型链上是否在同一个原型链 返回真假
  --衍生: 也可以做类型的判断  alert(arr instanceof Array); 这个和上面的两个判断类型不是最好的方法

apply and call 解析

 Function.apply(obj,args)方法能接收两个参数
 obj:这个对象将代替Function类里this对象
 args:这个是数组,它将作为参数传给Function(args-->arguments)

     call:和apply的意思一样,只不过是参数列表不一样.

 Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
总结:用法基本相同,参数不同;

function Aaa(name,age){
this.name = name;
this.age = age;
this.showName = function(){
alert(this.name);
}
}
function Bbb(name,age,sex){
Aaa.apply(this,arguments); // arguments是一个数组集合
// Aaa.call(this,name,age);
this.sex = sex;
}
var a1 = new Aaa();
var b1 = new Bbb('jack',23,'gril');
alert( b1.name );
alert( b1.age );
b1.showName();

toString():把对象转成字符串  
系统对象下面都是自带的,自己写的都是通过原型链在Object下挂载的

/*var arr = [];
alert( arr.toString == Object.prototype.toString ); //false*/


/*function Aaa(){
}


var a1 = new Aaa();
alert( a1.toString == Object.prototype.toString ); //true*/


对于数字进制转化可以接受一个参数比如16 进制(16)
查看类型:alert( Object.prototype.toString.call(arr) );
最完美的判断类型:
       是不是数组:alert( Object.prototype.toString.call(arr) == '[object Array]' );

  上面连个在特殊情况下失效,不过很少见: 跨页面的情况下<ifream>下

总结:判断检测对象的几种方法:
   普通类型: typeof
   引用类型:
              <1>: arr instanceOf Array  检测arr是不是在数组的原型链中
             <2>: arr.constructor == Array  检测对象的构造函数是不是Array
             <3>: Objcet.prototype.toString.call(arr) == '[objcet Array]' //  后面一个都是大写.

封装的判断数组的函数:

function showArray(arr){
if(Array.isArray){ // 支持ECMAScript 5新属性支持的浏览器到ie8以上
return (Array.isArray(arr));
}else{
return Object.prototype.toString.call(arr) == '[object Array]';
}
}

string  number转换: alert('11'+2) == '112'  
                                    alert('11'-2) == 9
                                    alert(9-'11') =-3  
                                    alert(9+'11')=='911'











0 0