• JS笔记加强版3


    JS 面向对象及组件开发
     
    JS的面向对象:
     
    1、什么是面向对象编程
     
    用对象的思想去写代码,就是面向对象编程
    过程式写法
    面向对象写法
    我们一直都在使用对象
    数组 Array 时间 Date
    var date = new Date();
    var arr = new Array(); //[] //我们把系统自带的对象,叫做系统对象
    面向对象编程(OOP)的特点
    抽象:抓住核心问题
    封装:只能通过对象来访问方法
    继承:从已有对象上继承出新的对象
    多态:多对象的不同形态
     
    2、对象的组成
     
    方法(行为、操作)——函数:过程、动态的
    属性——变量:状态、静态的
     
    var arr = [];
    arr.number = 10; //对象下面的变量:叫做对象的属性
    arr.test = function(){ //对象下面的函数 : 叫做对象的方法
    alert(123);
    };
     
    arr.test(); //123
     
    3、创建第一个面向对象程序
     
    为对象添加属性和方法
    Object对象
    this指向
    创建两个对象 : 重复代码过多
     
    //var obj = {};
    var obj = new Object(); //创建了一个空的对象
    obj.name = '小明'; //属性
    obj.showName = function(){ //方法
     
    //alert(obj.name);
    alert(this.name); // this指向的就是obj
     
    };
     
    obj.showName(); //小明
     
    4、工厂方式
     
    //工厂方式 : 面向对象中的封装函数
     
    function createPerson(name){
     
    //1.原料
    var obj = new Object();
    //2.加工
    obj.name = name;
    obj.showName = function(){
    alert( this.name );
    };
    //3.出场
    return obj;
     
    }
     
    var p1 = createPerson('小明');
    p1.showName();
    var p2 = createPerson('小强');
    p2.showName();
     
    5、对象的引用
     
    var a = 5;
    var b = a;
    b += 3;
    alert(b); //8
    alert(a); //5 基本类型 : 赋值的时候只是值的复制
     
     
    var a = [1,2,3];
    var b = a;
    b.push(4);
    alert(b); //[1,2,3,4]
    alert(a); //[1,2,3,4] 对象类型 : 赋值不仅是值的复制,而且也是引用的传递
     
    var a = [1,2,3];
    var b = a;
    b = [1,2,3,4]; // b又重新占了一个内存地址,和原来的无关
    alert(b); //[1,2,3,4]
    alert(a); //[1,2,3]
     
    var a = 5;
    var b = 5;
    alert(a == b); //基本类型 : 值相同就可以
     
    var a = [1,2,3];
    var b = [1,2,3];
    alert( a == b ); //false //对象类型 : 值和引用都相同才行
     
    var a = [1,2,3];
    var b = a;
    alert( a==b ); //true
     
    6、工厂方式,构造函数的写法:
     
    首字母大写、New 关键字提取、This指向为新创建的对象
     
    当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this(隐式返回)
     
    构造函数:new后面调用的函数,即用来创建对象的函数,叫做构造函数
     
    // CreatePerson()构造函数:
    function CreatePerson(name){
     
    //省略new Object和最后的return obj
     
    this.name = name;
    this.showName = function(){
    alert( this.name );
    };
     
    }
     
    var p1 = new CreatePerson('小明');
    p1.showName();
    var p2 = new CreatePerson('小强');
    p2.showName();
     
    alert( p1.showName == p2.showName ); //false ,值虽然相同,但是引用的 内存地址不同
     
    存在的问题:对象的引用、浪费内存
     
    7、原型-prototype
     
    原型 : 重写对象方法,让相同方法在内存中存在一份。就是去改写对象下面公用的方法或者属性 , 让公用的方法或者属性在内存中存在一份 ( 提高性能 )
     
    原型 : CSS中的class,可以重用,但优先级没style高
    普通方法 : CSS中的style,不可以重用,优先级高
     
    即原型可以重用,但优先级没有普通方法高。
     
    var arr = [];
    arr.number = 10;
    Array.prototype.number = 20;
     
    alert(arr.number); //10
     
     
    普通方法:
     
    var arr = [1,2,3,4,5];
    var arr2 = [2,2,2,2,2];
     
    arr.sum = function(){
     
    var result = 0;
    for(var i=0;i<this.length;i++){
    result += this[i];
    }
    return result;
     
    };
    arr2.sum = function(){
     
    var result = 0;
    for(var i=0;i<this.length;i++){
    result += this[i];
    }
    return result;
     
    };
     
    alert( arr.sum() ); //15
    alert( arr2.sum() ); //10
     
    原型方法 :
     
    var arr = [1,2,3,4,5];
    var arr2 = [2,2,2,2,2];
     
    Array.prototype.sum = function(){
    var result = 0;
    for(var i=0;i<this.length;i++){
    result += this[i];
    }
    return result;
    };
     
    alert( arr.sum() ); //15
    alert( arr2.sum() ); //10
     
    8、工厂方式之原型:面向对象的写法:
     
    原型prototype : 要写在构造函数的下面
     
    function CreatePerson(name){
     
    this.name = name;
     
    }
     
    CreatePerson.prototype.showName = function(){
    alert( this.name );
    };
     
    var p1 = new CreatePerson('小明');
    p1.showName();
    var p2 = new CreatePerson('小强');
    p2.showName();
     
    alert( p1.showName == p2.showName ); //true
     
    总结面向对象写法:构造函数加属性,原型加方法
     
    function 构造函数(参数){
    this.属性 = 参数;
    }
    构造函数.prototype.方法 = function(){ ... };
     
     
     
    调用写法:
     
    var 对象1 = new 构造函数();
    对象1.方法();
     
     
    9、面向对象的例子:
     
    原则:
    1)先写出普通的写法,然后改成面向对象写法
    2)普通方法变型
    3)尽量不要出现函数嵌套函数
    4)可以有全局变量
    5)把onload中不是赋值的语句放到单独函数中
     
    改成面向对象:
    1)全局变量就是属性
    2)函数就是方法
    3)Onload中创建对象
    4)改this指向问题
    5)事件ev要放到事件函数中:
    var ev = ev || window.event;
    return false;
     
     
     
     
    例子:面向对象的选项卡:
     
    第一步:普通方法:
     
    <script>
     
    window.onload = function(){
     
    var oParent = document.getElementById('div1');
    var aInput = oParent.getElementsByTagName('input');
    var aDiv = oParent.getElementsByTagName('div');
     
    for(var i=0;i<aInput.length;i++){
    aInput[i].index = i;
    aInput[i].onclick = function(){
     
    for(var i=0;i<aInput.length;i++){
    aInput[i].className = '';
    aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[this.index].style.display = 'block';
    };
    }
     
    };
     
    </script>
     
    第二步:
    先变型:
    尽量不要出现函数嵌套函数
    可以有全局变量
    把onload中不是赋值的语句放到单独函数中
     
     
     
    <script>
     
    var oParent = null;
    var aInput = null;
    var aDiv = null;
     
    window.onload = function(){
     
    oParent = document.getElementById('div1');
    aInput = oParent.getElementsByTagName('input');
    aDiv = oParent.getElementsByTagName('div');
     
    init();
     
    };
     
    function init(){
    for(var i=0;i<aInput.length;i++){
    aInput[i].index = i;
    aInput[i].onclick = change;
    }
    }
     
    function change(){
    for(var i=0;i<aInput.length;i++){
    aInput[i].className = '';
    aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[this.index].style.display = 'block';
    }
     
    </script>
     
     
    第三步:
     
    全局变量就是属性
    函数就是方法
    Onload中创建对象
    改this指向问题
     
     
     
    <script>
     
    window.onload = function(){
     
    var t1 = new Tab('div1');
    t1.init();
    t1.autoPlay();
     
    var t2 = new Tab('div2');
    t2.init();
    t2.autoPlay();
     
    };
     
    function Tab(id){
    this.oParent = document.getElementById(id);
    this.aInput = this.oParent.getElementsByTagName('input');
    this.aDiv = this.oParent.getElementsByTagName('div');
    this.iNow = 0;
    }
     
    Tab.prototype.init = function(){
    var This = this;
    for(var i=0;i<this.aInput.length;i++){
    this.aInput[i].index = i;
    this.aInput[i].onclick = function(){
    This.change(this);
    };
    }
    };
     
    Tab.prototype.change = function(obj){
    for(var i=0;i<this.aInput.length;i++){
    this.aInput[i].className = '';
    this.aDiv[i].style.display = 'none';
    }
    obj.className = 'active';
    this.aDiv[obj.index].style.display = 'block';
    };
     
    Tab.prototype.autoPlay = function(){
     
    var This = this;
    setInterval(function(){
     
    if(This.iNow == This.aInput.length-1){
    This.iNow = 0;
    }
    else{
    This.iNow++;
    }
     
    for(var i=0;i<This.aInput.length;i++){
    This.aInput[i].className = '';
    This.aDiv[i].style.display = 'none';
    }
    This.aInput[This.iNow].className = 'active';
    This.aDiv[This.iNow].style.display = 'block';
     
    },2000);
     
    };
     
    </script>
     
     
    10、包装对象 : JS基于原型的程序、系统对象也是基于原型的程序
     
    尽量不要去修改或者添加系统对象下面的方法和属性
     
    基本类型都有自己对应的包装对象 : String Number Boolean
     
    基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,然后包装对象消失
     
     
    var str = 'hello';
     
    String.prototype.lastValue = function(){
    return this.charAt(this.length-1);
    };
     
    alert( str.lastValue() ); // o
     
     
     
    var str = 'hello';
     
    str.number = 10; //创建对象后,包装对象立即消失
     
    alert( str.number ); //undefined 创建的新对象
     
     
    11、原型链
     
    原型链 : 实例对象与原型之间的连接,叫做原型链
     
    原型链的最外层 : Object.prototype
     
    对象调用的属性在构造函数中没有的话,会沿着原型链到该对象的prototype原型中查找,若还是没有,则沿着最外层原型链到Object.prototype中查找
     
     
    function Aaa(){
    this.num = 10; // 优先级最高
    }
    Aaa.prototype.num = 20; // 优先级第二
    Object.prototype.num = 30; //优先级最后
     
    var a1 = new Aaa();
    alert(a1.num);
     
     
    12、hasOwnProperty : 看是不是对象自身下面的属性
     
    var arr = [];
    arr.num = 10;
    Array.prototype.num2 = 20;
     
    alert( arr.hasOwnProperty('num') ); //true //只是arr中的属性,其余的数组对象没有
     
    alert( arr.hasOwnProperty('num2') ); //false //数组对象原型中的属性,所有数组都有这个属性
     
    alert( arr.hasOwnProperty == Object.prototype.hasOwnProperty ); //true // 这个属性是在最外层的Object原型上
     
     
     
    13、constructor : 查看对象的构造函数
     
    function Aaa(){
    }
     
    var a1 = new Aaa();
     
    alert( a1.constructor ); //Aaa
     
    var arr = [];
    alert( arr.constructor == Array ); //true
     
     
    function Aaa(){
    }
    Aaa.prototype.constructor = Aaa; //每一个函数都会有的,都是自动生成的
     
    Aaa.prototype.constructor = Array; // 修改了对象的构造函数,避免这样做
     
     
    function Aaa(){
    }
     
    Aaa.prototype.name = '小明';
    Aaa.prototype.age = 20;
     
    var a1 = new Aaa();
    alert( a1.constructor );
     
    //若用JSON形式写Aaa的属性,那么a1的constructor不是Aaa了,而是JSON对象,即Object
    Aaa.prototype = {
    constructor : Aaa,
    name : '小明',
    age : 20
    };
     
     
     
    function Aaa(){
    }
     
    Aaa.prototype.name = 10;
    Aaa.prototype.constructor = Aaa;
     
    for( var attr in Aaa.prototype ){ //遍历不到JS内置属性,只能遍历到name
    alert(attr);
    }
     
     
     
    14、instanceof : 对象与构造函数在原型链上是否有关系
     
    //自定义对象
    function Aaa(){
    }
     
    var a1 = new Aaa();
     
    alert( a1 instanceof Object ); //true
     
    //系统内置对象
    var arr = [];
     
    alert( arr instanceof Array ); //true
     
     
    15、toString() :
     
    toString() : 系统对象下面都是自带的,不需要经过原型链寻。自己写的对象都是通过原型链找Object下面的。
     
    var arr = [];
    alert( arr.toString == Object.prototype.toString ); //false
     
    /function Aaa(){
    }
    var a1 = new Aaa();
    alert( a1.toString == Object.prototype.toString ); //true
     
     
    toString() : 把对象转成字符串
     
    var arr = [1,2,3];
     
    Array.prototype.toString = function(){
    return this.join('+');
    };
     
    alert( arr.toString() ); //'1+2+3'
     
     
    toString() : 进制转换
    var num = 255;
    alert( num.toString(16) ); //'ff' //255转成16进制
     
     
    利用toString做类型的判断 : (推荐)
     
    var arr = [];
     
    alert( Object.prototype.toString.call(arr) == '[object Array]' ); //'[object Array]'
     
    用constructor和instanceof判断类型在iframe中判断不出
     
    alert( arr.constructor == Array ); //false
    alert( arr instanceof Array ); //false
     
     
     
    16、继承
     
    继承 :在原有对象的基础上,略作修改,得到一个新的对象。不影响原有对象的功能。
     
    子类不影响父类,子类可以继承父类的一些功能 ( 代码复用 )
     
    1)拷贝继承:
     
    属性的继承 : 调用父类的构造函数 call
     
    方法的继承 : for in : 拷贝继承 (jquery也是采用拷贝继承extend)
     
    function CreatePerson(name,sex){ //父类
    this.name = name;
    this.sex = sex;
    }
    CreatePerson.prototype.showName = function(){
    alert( this.name );
    };
     
    var p1 = new CreatePerson('小明','男');
    //p1.showName();
     
     
    function CreateStar(name,sex,job){ //子类
     
    CreatePerson.call(this,name,sex); //继承 call改变this指向为对象
     
    this.job = job;
     
    }
     
    //不能用对象的赋值,CreateStar.prototype = CreatePerson.prototype; 都指向同一内存地址,改变其中一个,另一个也会改变
     
    extend( CreateStar.prototype , CreatePerson.prototype );
     
    CreateStar.prototype.showJob = function(){
    };
     
    var p2 = new CreateStar('黄晓明','男','演员');
     
    p2.showName();
     
     
    function extend(obj1,obj2){ //把父类所有的非对象属性给子类
    for(var attr in obj2){
    obj1[attr] = obj2[attr];
    }
    }
     
     
     
     
    2)类式继承:
     
    类 : JS是没有类的概念的 , 把JS中的构造函数看做的类
     
    要做属性和方法继承的时候,要分开继承,避免子类对象之间的修改相互影响属性
     
    属性的继承 : 调用父类的构造函数 call
     
    方法的继承 : 利用构造函数(类)继承的方式
     
     
    function Aaa(){ //父类
    this.name = [1,2,3];
    }
    Aaa.prototype.showName = function(){
    alert( this.name );
    };
     
     
    function Bbb(){ //子类 ,属性的继承
     
    Aaa.call(this);
     
    }
     
    //方法的继承
    var F = function(){};
    F.prototype = Aaa.prototype; //只能继承方法
    Bbb.prototype = new F();
    Bbb.prototype.constructor = Bbb; //修正指向问题
     
    var b1 = new Bbb();
    b1.name.push(4);
    alert( b1.name ); //[1,2,3,4]
     
    var b2 = new Bbb();
    alert( b2.name );//[1,2,3]
     
     
     
    3)原型继承:
     
    借助原型来实现对象继承对象
     
    var a = {
    name : '小明'
    };
     
    var b = cloneObj(a);
     
    b.name = '小强';
     
    alert( b.name );//小强
    alert( a.name );//小明
     
    function cloneObj(obj){
     
    var F = function(){};
     
    F.prototype = obj;
     
    return new F();
     
    }
     
     
    拷贝继承: 通用型的 有new或无new的时候都可以
     
    类式继承: new构造函数
     
    原型继承: 无new的对象
     
    17、组件开发 : 多组对象,像兄弟之间的关系( 代码复用的一种形式 )
     
    对面向对象的深入应用(UI组件,功能组件)
    将 配置参数、方法、事件,三者进行分离
     
     
    18、自定义事件 : 主要是跟函数有关系,就是让函数能够具备事件的某些特性
     
    window.addEventListener('show',function(){
    alert(1);
    },false);
    window.addEventListener('show',function(){
    alert(2);
    },false);
    window.addEventListener('show',function(){
    alert(3);
    },false);
     
    show(); //主动触发自定义事件
  • 相关阅读:
    ASP.NET MVC分部类的使用
    窗体初始化完毕后隐藏窗体
    让每个用户都有同样的输入法配置
    昨夜的失眠--从数据备份所想到的.
    电子书下载
    Microsoft .Net 框架 SDK 快速入门教程
    .net书籍代码下载 [雪冬寒'Blog]
    VISUAL C#.NET中文版WEB服务开发基础
    Citrix相关技术
    OA在线试用
  • 原文地址:https://www.cnblogs.com/hello-web/p/7221443.html
Copyright © 2020-2023  润新知