面向对象

2018-11-20  本文已影响0人  致自己_cb38

1、面向对象(OOP | OO)

2、面向过程

3、面向对象的特点:(封装,继承,抽象(多态))

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
function A(){ //构造函数
    this.name='lisisi';
    this.age = 18;
}
A.prototype.sss = 'sss';
A.prototype.func = function(){
    console.log(this.name);
}
A.prototype.func1 = function(){
    console.log(this.age);
}
function B(){
    A.call(this);  //修改A的this,相当于A里面的属性是给B添加的。
}
// B.prototype = A.prototype;  //引用类型
for(let m in A.prototype){
    B.prototype[m] = A.prototype[m];
}
let a = new A();
let b = new B();
// B.prototype=A.prototype;
console.log(B.prototype);
console.log(A.prototype);
B.prototype.func1 = function(){
    console.log(1);
}
b.func1(); //1
a.func1(); //18
</script>
</body>
</html>

4、对象的组成

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
//工厂方法创建对象
function MakeStu(name,weight){  //构造函数 参数就是原料
    //加工
    var obj = new Object();
    //属性
    obj.name = name;
    obj.weight = weight;
    //方法
    obj.getName = function(){
        console.log('我的名字叫:'+this.name);
    }
    obj.getWeight = function(){
        console.log('我的体重是:'+this.weight);
    }
    //出厂
    return obj;
}
var obj1 = MakeStu('limao','100kg');
obj1.getName();
obj1.getWeight();
var obj2 = MakeStu('lihaoshung','90kg');
obj2.getName();
obj2.getWeight();
</script>
</body>
</html>

5、this 函数的调用者就是this(每一个函数都具有自己的调用对象)

div.onclick = function(){
    alert(this);
};

6、new : 一个函数( 创建对象实例)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
    function show(){
        //this=new Object();
        alert(this);
        //return this;
    }
    show(); //window
    new show(); //object
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    //严格模式
    function A(name){
        'use strict';
        this.name = name;
    }
    let a = new A('ahuang');
    console.log(a.name); //ahuang


    //递归
    function B(name){
        //this 指向新创建的实例
        if (!(this instanceof B) ) {
            return new B(name);
        }
        this.name = name;
    }
    let b1 = new B('zhangsan');
    console.log(b1.name); //zhangsan
    let b2 = B('lisi');
    console.log(b2.name); //lisi


    function C(name){
        if (!(new.target == C)) {
            throw new Error('这个对象必须使用new来创建对象');
        }
        this.name = name;
    }
    let c1 = new C('ergouzi'); //ergouzi
    console.log(c1.name);
    let c2 = C('wangwu'); //这个对象必须使用new来创建对象
</script>
</html>

7、构造函数里面的return语句:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    // 简单数据类型
    function A(name){
        this.name = name;
        return 123;
    }
    let a = new A('12');
    console.log(a); //12


    //返回this
    function B(name){
        this.name = name;
        return this;
    }
    let b = new B('34');
    console.log(b); //34


    //返回其他对象
    function C(name){
        this.name = name;
        return {
            "a": a
        };
    }
    let c = new C('56');
    console.log(c); //"a":a
</script>
</html>

8、Object对象,是所有JS对象的基础。Object 的原型指向null。一切对象的基础是null,null也叫空。

eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
    console.log(Object.prototype.__proto__); //null
</script>
</body>
</html>

9、Object.create()有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。

eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    function A(name){
        this.name = name;
    }
    let a = new A('lisi');
    let b = Object.create(a);
    console.log(b); //zhangsan
    b.name = 'zhangsan';
    console.log(a.name) //lisi
</script>
</html>

10、对于对象来说,每一个属性都有四个描述。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    let obj1 = new Object();
    obj1.p1 = 'zhangsan';
    obj1.p2 = 18;
    let obj2 = Object.create(obj1,{
        p1:{
            value: 'zhangsan', //值
            enumerable: false, //遍历 有问题
            configurable: true, //修改值
            writable: true //删除属性
        },
        p2:{
            value: 18,
            enumerable: false,
            configurable: true,
            writable: true
        }
    });
    for(let i in obj2){
        console.log(i,obj2[i]);
    }
    obj1.p1 = 'lisi';
    console.log(obj1.p1); //lisi
    delete obj1.p2;
    console.log(obj1.p2); //undefined
</script>
</html>

enumerable:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    let obj = {
        a: 'a',
        b: 'b',
        c: 'c',
    };
    for(let i in obj){
        console.log(i,obj[i]); //aa bb cc
    }

    console.log('-------------');
    Object.defineProperty(obj,'c',{
        value: 1,
        enumerable: false, //遍历
    })
    for(let i in obj){
        console.log(i,obj[i]); //aa bb
    }
</script>
</html>

11、JavaScript的面向对象是基于constructor(构造函数)与prototype(原型链)的。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    let arr1 = new Array(1,2,3,4,5,6);
    let arr2 =new Array(7,8,9);
    //原型 给每个对象添加相同的属性
    Array.prototype.sum = function(){
        let sum = 0;
        for (var i = 0; i < this.length; i++) {
            sum += this[i];
        }
        return sum;
    };
    console.log(arr1.sum()); //21
    console.log(arr2.sum()); //24
</script>
</html>

eg2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
function MakeStu(name,weight){
    // var this = new Object();
    //属性
    this.name = name;
    this.weight = weight;
    //return this;
}
//方法
MakeStu.prototype.getName = function(){
    console.log('我的名字叫:'+this.name);
}
MakeStu.prototype.getWeight = function(){
    console.log('我的体重是:'+this.weight);
}
var obj1 = new MakeStu('limao','100kg');
obj1.getName();
obj1.getWeight();
var obj2 =new  MakeStu('lihaoshung','90kg');
obj2.getName();
obj2.getWeight();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
    Object.prototype.name = function(){
        console.log('a');
    };
    let obj = new Object(); //a
    let obj2 = new Object(); //a
    obj.name();
    obj2.name();
    //给对象再次添加相同的属性,旧的属性会被新的属性覆盖
    obj2.name = function(){
        console.log('b')
    };
    obj.name(); //a
    obj2.name(); //b
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    function A(){
        this.a = '1';
    }
    let b = new A();
    console.log(b.__proto__); //object
    console.log(A);
</script>
</html>

12、 getPrototypeOf 获取obj对象实例的原型

格式:Object.getPrototypeOf(obj)
eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    function A(name){
        this.name = name;
    }
    let a = new A('lisi');
    console.log(Object.getPrototypeOf(a)); //object 获取实例对象的原型
    console.log(a.__proto__); //object

    Object.getPrototypeOf({}) === Object.prototype; //true
    // {}:new Object与Object的原型一致   构造函数的原型与对象的原型一致
    Object.getPrototypeOf(Object.prototype) === null;
    // Object对象的原型的原型指向null,null是原型链的顶点
/*
let o = new Object();
o.__proto__
Object.peototype
Object.peototype.peototype
null
*/

    function f(){}
    Object.getPrototypeOf(f) === Function.prototype; //true
    // 构造函数的原型与内置对象Function的原型一致   f === new Function()
</script>
</html>

13、isPrototypeOf 判断该对象是否为参数对象的原型

格式:Object.prototype.isPrototypeOf()
eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    let a = new Array();
    console.log(Array.prototype.isPrototypeOf(a)); //true Array.prototype === a.__proto__
</script>
</html>

14、设置一个对象的prototype对象,返回参数对象本身

eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    let a = new Array();
    console.log(Object.getPrototypeOf(a)); //Array
    Object.setPrototypeOf(a,Number.prototype);
    console.log(Object.getPrototypeOf(a)); //Number
</script>
</html>

15、getOwnPropertyNames 成员是参数对象本身的所有属性的键名,不包含继承的属性键名。hasOwnProperty 用于判断某个属性定义在对象自身,还是定义在原型链上。

格式:
Object.getOwnPropertyNames()
Object.prototype.hasOwnProperty()
eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    function A(name){
        this.name = name;
        function say(){
            console.log('s');
        }
    }
    A.prototype.m = function(){
        console.log('m');
    };
    function B(){
        A.call(this);
        this.age = 18;
        this.sex = 'man';
    }
    for(let i in A.prototype){
        B.prototype[i] = A.prototype[i];
    }
    let b = new B();
    b.m(); //m b继承a的属性
    // b.name();   is not a function b本身的属性
    //console.log(Object.getOwnPropertyNames(b)); name say age sex
    console.log(B.prototype.hasOwnProperty('name')); //false
</script>
</html>

16、私有属性

eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    function A(name){
        let b = name;
        this.getName = function(){
            console.log(b); //私有属性
        };
    }
    let a = new A('lili');
    // console(a.name) is not a function
    a.getName();
</script>
</html>

17、命名空间

eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
<script>
    //大型项目组 防止污染
    var Li = {
        this.F = function(){

        }
        this.S = function(){

        }
    }
    Li.F();
</script>
</html>

18、json:(字符串)数据传输格式

json 对象:json字符串解析出来的对象,或者就是个对象。但是这个对象有限制。键必须是双引号包起来。值必须是简单类型或者数组。
eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
//json 创建对象的格式
let json = {
    "name":"zhangsan",
    "age":19,
    "getName": function(){
        console.log(this.name);
    }
};
//单体对象(适用于只有一个对象的场景)
//对象转化为字符串
console.log(JSON.stringify(json));
</script>
</body>
</html>

19、闭包:

函数的作用域是定义的地方,而不是函数调用的地方。
eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
function t(){
    var a = 10;
  //往外寻找变量,若在函数内部找不到,就去外部寻找(最外层是window),若外部没有找到会产生not defined
    return function(){
        console.log(++a);
    }
}
var a = 1000;
var tmp = t();
tmp(); //11
/*
function t(){
    var a = 10;
    //return = function(){
        console.log(++a);
    }; ;
}
var a = 1000;
var tmp = function(){
        console.log(++a);
    };
tmp(); //1001
*/
</script>
</body>
</html>

20、js的数据类型分为简单类型与复杂类型(引用类型)

eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
    let arr = [1,2,3];
    let arr1 = arr;
    arr1.push(8);
    console.log(arr); //1,2,3,8
    console.log(arr1); //1,2,3,8
</script>
</body>
</html>

21、instanceof 判断某一个实例对象是否是某一个对象的实例。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
//数组的实例
let a = new Array();
console.log(a instanceof Number); //false
function Say(name){
    this.name = name;
}
let s = new Say();
console.log(s instanceof Say); //true
</script>
</body>
</html>

22、案例

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        button{
            width: 80px;
            height: 40px;
            margin: 50px;
        }
        div div{
            width: 200px;
            height: 200px;
            border: 1px solid #ccc;
            display: none;
        }
        .active{
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div id="tab">
        <button class="active">vf</button>
        <button>vdf</button>
        <button>vdsv</button>
        <div style="display: block;">ddfa</div>
        <div>fvd</div>
        <div>fva</div>
    </div>
</body>
<script>
    function Tab(id){
        //this = new Tab('tab');
        // _this = this;
        let obj = this;//保存现场的this   this进入一个新的函数会改变,把this赋值给一个不会改变的量
        //属性 初始化
        this.con = document.getElementById('tab');
        this.btn = this.con.getElementsByTagName('button');
        this.div = this.con.getElementsByTagName('div');
        for (var i = 0; i < this.btn.length; i++) {
            this.btn[i].index = i;
            this.btn[i].onclick = function(){
                //事件内部this发生变化,this变成按钮 this = this.btn[i]
                obj.fclick(this);
            };
        }
    }
    //方法
    //原型:同时给多个对象添加属性
    Tab.prototype.fclick = function(btn){
        //this 函数的调用者 Tab
        for (var j = 0; j < this.btn.length; j++) {
            this.btn[j].className = '';
            this.div[j].style.display = 'none';
        }
        //用到按钮的this btn = this = this.btn[i]
        btn.className = 'active';
        this.div[btn.index].style.display = 'block';
    };
    new Tab('tab');
    // new Tab('abc'); 若使用_this = this(全局变量),再次构造函数会造成函数覆盖,可在构造函数中var/let 变量 = this解决该问题
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
    let a = [1,2,3];
    let b = [];
    for(var j in a){
        b.push(j);
    }
    console.log(a); //123
    console.log(b); //123
    b.push(8);
    console.log(a); //123
    console.log(b); //1238
    let arr = [1,2,3];
    let arr1 = [...arr];
    arr1.push(8);
    console.log(arr); //123
    console.log(arr1); //1238
</script>
</body>
</html>
function Drag(id){
    this.d = document.getElementById(id);
    //初始化
    this.x = 0;
    this.y = 0;
    let obj = this;
    this.d.onmousedown= function(ev){
        var ev = ev || event;
        obj.mousedown(ev)
    };
}
Drag.prototype.mousedown = function(ev){
    //计算鼠标相对div的距离
    this.x = ev.clientX - this.d.offsetLeft ;
    this.y = ev.clientY - this.d.offsetTop;
    let obj = this;
    document.onmousemove = function(ev){
        var ev = ev || event;
        obj.mousemove(ev)
    }
    document.onmouseup = this.mouseup;
}
Drag.prototype.mousemove = function(ev){
    this.d.style.left = ev.clientX - this.x + 'px';
    this.d.style.top = ev.clientY - this.y+'px';
};
Drag.prototype.mouseup = function(){
    document.onmousemove = null;
    document.onmouseup = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        div{
            width:200px;
            height:200px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="move"></div>
</body>
<script src="Drag.js"></script>
<script>
function LimitDrag(id){
    Drag.call(this,id); //this LimitDrag()
}
for(let a in Drag.prototype){
    //[a]:键名(mousedown mousemove mouseup)
    LimitDrag.prototype[a] = Drag.prototype[a];
}
//重写
LimitDrag.prototype.mousemove = function(ev){
    //计算div相对浏览器可视窗口的距离
    let l = ev.clientX - this.x;
    let t = ev.clientY - this.y;
    //判断拖拽边界
    if(l<0){
        l=0
    }else if(l>window.innerWidth - this.d.offsetWidth){
        l = window.innerWidth - this.d.offsetWidth;
    }
    if(t<0){
        t=0
    }else if(t>window.innerHeight-this.d.offsetHeight){
        t =window.innerHeight-this.d.offsetHeight;
    }
    this.d.style.left = l + 'px';
    this.d.style.top = t+'px';
};
new LimitDrag('move');
</script>
</html>
上一篇 下一篇

猜你喜欢

热点阅读