05-js面向对象

面向对象

一、初识面向对象

JS也是面向对象的。基本上所有的高级语言都是面向对象编程。面向对象是一种思想。

常见几种思想:
面向过程:C语言 没有类 没有对象
面向对象:JAVA,C++,JS(恶心)
面向切面:Spring IOC AOP

1.面向对象特征

特征分别为:抽象、封装、继承、多态

1)抽象

抽象:把一个具体问题抽象化。

2)封装

封装:把属性和方法封装到类中,在JS中重点说对象。封装实现就是是对象内部的变化对外界是不可见的。

var obj = {
    name:"wangcai",
    age:15,
    say:function(){
        console.log("say...");
    }
}
3)继承

一个类可类可以继承另一个类,在JS,类是通过函数表达式。

<script>
    class NBAPlayer{
        constructor(name,age)
        {
            this.name = name;
            this.age = age;
        }

        score = 50;
        run(){
            console.log("run...");
        }
        static it = "123";
    }
    var nba = new NBAPlayer("乔丹",35);
    console.log(nba.name);     //乔丹
    console.log(nba.age);       //35
    console.log(nba.score);     //50
    console.log(nba.run());     //run...  undefined
    console.log(NBAPlayer.it);  //123

    //静态对象只能通过类名调用,不能使用对象调用
</script>

4)多态

多态其实就是把做的内容和谁去做分开。

    var makeSound=function (animal) {
        animal.sound();
    }
    var Duck=function () {
    }
    var Dog=function () {
    }
    Duck.prototype.sound=function () {
        console.log("嘎嘎嘎")
    }
    Dog.prototype.sound=function () {
        console.log("旺旺旺")
    }
    makeSound(new Duck());
    makeSound(new Dog());

二、JS默认提供了很多类

1.Number 类
<script>
    
    var n = new Number("100");
    console.log(n); // Number {100}
    console.log(typeof n); // object
    
    console.log(n instanceof Number);  // true
</script>

instanceof 是一个运算符 判断一个对象是否属性某个类

2. String 类
<script>
    var str = new String("hello oop");
    console.log(str)  // {"hello oop"}
    console.log(typeof str)  // object
    console.log(str instanceof String);  // true
    console.log(str instanceof Number);  // false

    // 对象 也叫 实例
    // 类  也叫 构造器(JS特有)
</script>
3.Boolean类

Boolean只有两个数值,true或者false。

<script>
    var f = new Boolean(false);
    console.log(f)  // {false}
    console.log(typeof f)  // object
    console.log(f instanceof Boolean)  // true
</script>

4.Object 构造器
<script>
    // 按理说,你要想写一个对象,都需要通过new一个构造器 得到一个对象
    var obj = new Object();  // new一个构造器得到一个对象
    obj.name = "wc";
    obj.age = 110;
    console.log(obj); // {name: "wc", age: 110}

    // 下面的写法是上面的写法的语法糖(是上面写法的简写)
    var obj2 = {  // 字面量形式声明一个对象
        name:"xiaoqiang",
        age:100
    }
</script>
5.Date日期
<script>
    // Date 日期
    var d = new Date();
    console.log(d);
    console.log(d.getFullYear())
</script>
6.Math
<script>
    // Math 数学计算相关  不需要new  单体内置类
    // 常驻内存不需要new
    var r = Math.random();
    console.log(r);
</script>
7.Array类
<script>
    // Array是一个内置类   new
    var arr = new Array("a","b","c");
    console.log(arr); // ["a", "b", "c"]

    // 是上面的形式的语法糖
    var arr2 = ["d","e","f"];  // 字面量创建数组(对象)
    console.log(arr2); // ["d", "e", "f"]
</script>

除了上面列举的,还有很多其他类型…在这里不作详细的描述

三、JS中一切数据都是对象

一般对象都是以通过"."对自己内部属性进行访问,下面证明一切数据都是对象这一观点。

1.证明一:html元素是一个对象
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    // 证明一:html元素是一个对象
    let lis = document.getElementsByTagName("li"); yigeyuansudezh     //得到一个元素
    console.log(lis); // HTMLCollection  [li, li, li]
    console.log(lis[0])
    console.dir(lis[0])
    console.dir(lis[0] instanceof HTMLLIElement); // true

    let a = document.getElementsByTagName("a")[0];
    console.dir(a); // HTMLAnchorElement
    console.log(a instanceof HTMLAnchorElement)
</script>l
2. 证明二:数组也是对象
<script>
    // 证明二:数组也是对象   对象里面有一堆的属性和方法
    var arr = ["a","b","c"]; // 也是Array这个类
    console.log(arr); // ["a", "b", "c"]
    console.dir(arr);
    console.dir(typeof arr); // object
    console.log(arr.length);
    arr.push("d");
    console.log(arr);
    console.log(arr instanceof Array); // true
</script>
3.证明三:函数也是对象
<script>
    //函数也是对象
    function f(a,b) {
        console.log("f...")
    }
    console.dir(f)
    console.dir(f.name)
    console.dir(f.length)
    f.call()
    f.apply()
    f.bind()
    console.log(f instanceof Function); // true
    console.log(typeof f); // function

</script>
4.证明四:基本数据类型也是对象
<script>
    // 证明4:基本数据类型也是对象(基本数据类型在某些情况下也是对象)
    var a = 110; // 现在要证明a也是对象
    console.dir(a);  // 110
    console.log(typeof a) // number
    console.log(a instanceof Number) // false

    // 如果a不是对象  是不可能打点调用toFiexed
    console.log(a.toFixed(3)); // 110.000
    // 上面的a叫包装对象
    // 上面调用toFixed时,它会把a瞬间包装成一个对象

    var str = "hello";
    console.log(str.length);  // 5  str也是瞬间包装成对象了
    console.log(str.toUpperCase()); // HELLO

</script>
5.证明五:console也是对象 window也是对象
<script>
    // 证明5:console也是对象  window也是对象
    console.log("wc")
    console.dir(console)
    console.log(console instanceof Object)  // true

    console.dir(window)
    console.log(window instanceof Window)  // true
</script>

四、对象是属性的无序集合

操作集合:增删改查

如何访问对象里面的属性
1)打点调用(使用较多)
2)通过[]来调用
<script>
    var obj = {
        name:"wangcai",  // name叫属性名  “wangbai"叫属性值
        123:456, // 123是属性名(键),456是属性值(值)
        "1+1":2, // "1+1"是属性名   2是属性值
        "a":"hello",
        "b":null,
        "c":function () {
            console.log("c..")
        },
        "d":["1","2","3"],
        "e":{ x:"xxx" }
    }
    console.log(obj.name)
    console.log(obj[123]); // 456
    console.log(obj.a); // hello
    console.log(obj["1+1"]); // 2
    // 如果我们的键是一个变量  我们需要通过变量去访问  必须使用[]
    var k = "name";
    console.log(obj[k]); // wangcai
    //如果我们在全局定义的变量名字与 对象中定义的属性名字 相同,则需要通过[]进行访问
</script>
<script>
    // 访问一个对象中不存在的属性 结果是undefined
    var obj = {};
    console.log(obj.name);      //undefined

    // 操作对象中的属性之遍历对象 for in
    var obj = {
        name:"wangcai",
        age:100,
        say:function () {
            console.log("say...")
        }
    }
    for (var key in obj) {  // 通常遍历一个对象使用for in
        // key是一个变量
        //这里的key指的是属性名,而不是属性值

        console.log(obj[key]);
    }
    console.log(obj.length)     // undefined
    // 得不到一个对象中有多少个属性
    //数组可以得到长度,但是对象无法知道有多少属性

    let arr = ["a","b","c"];
    console.dir(arr)
    for (const key in arr) {  // 使用for in 并不能遍历出一个对象中所有的属性  如数组中的length和__proto__
        // console.log(key);
        console.log(arr[key])
    }
</script>
console.dir(obj);打印出该对象的所有属性和属性值.
<script>
    // 给添加添加新的属性
    var obj = {
        name:"wangcai"
    }
    console.log(obj.name); // 打印出obj中的name属性  访问
    obj.name = "xiaoqiang"; // 修改属性
    console.log(obj.name);  // 同名属性后面的会把前面的覆盖掉

    obj.age = 1100; // 新增属性
    obj["address"] = "北京"; //  新增属性
    console.log(obj)
</script>
如果对象中有对应的属性名,直接修改相应的属性值,如果没有,则在对象中创建新的属性名,赋值新的属性值。
<script>
    var obj = {
        name:"wangcai",
        age:100
    }
    console.log(obj)

    delete obj.age;
    console.log(obj)

    var a = 110;  // var的变量放到GO中,是不能删除的
    console.log(window.a)
    delete window.a;
    console.log(window.a)

    b = 666;  // 没有加var的变量  默认是可以删除的
    console.log(window.b) // 666
    delete window.b;
    console.log(window.b) // undefined

    let c = 111;
    delete c;  // delete用来删除一个对象上的属性
    console.log(c)
</script>
delete:操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。
delete object.property :object对象的名称,或计算结果为对象的表达式。 
delete object['property']:property 要删除的属性。 

五、读取对象中的属性有4大特征

1)configurable:表示是否可以被删除,true表示可以删除,默认true
2)writable:表示是否可以修改,true表示可以被修改,默认true
3)enumerate:表示是否可以枚举/输出 ,输出表示可以输出,默认true
4)value:当前的属性值,默认是undefined

<script>

    var obj = {
        name:"wangguowei"
    }

    //Object.getOwnPropertyDescriptor 获取属性的特征
    //writable: true, enumerable: true, configurable: true
    console.log(Object.getOwnPropertyDescriptor(obj,"name"));

    var a = 48;
    b = 68;

    //writable: true, enumerable: true, configurable: false 不可被修改
    console.log(Object.getOwnPropertyDescriptor(window,"a"));

    //writable: true, enumerable: true, configurable: true 可以被修改
    console.log(Object.getOwnPropertyDescriptor(window,"b"));

    var arr = ["a"];
    //writable: true, enumerable: false, configurable: false 不可枚举/输出 不可被修改
    console.log(Object.getOwnPropertyDescriptor(arr,"length"));

</script>

 Object.getOwnPropertyDescriptor 获取属性的特征

六、属性的分类

对象上的属性是分成两类的: 私有属性、公有属性

<script>
    var obj = {
        name:"wangcai",
        age:100
    }

    console.log(obj.hasOwnProperty("name")); // true 查看name是否是obj的私有属性
    console.log(obj.hasOwnProperty("age"));  // true

    // 公有属性  原型属性
    console.log(obj)
    console.dir(obj.hasOwnProperty("toString")); // false 查看toString是否是obj的私有属性
    console.log(obj.hasOwnProperty("__proto__")); // false 查看__proto__是否是obj的私有属性
    console.log(obj.__proto__.hasOwnProperty("toString")); // true  // 查看toString是否是obj.__proto__这个对象的私有属性

    // 对于obj来说:name和age是它的私有属性  toString是它的公有属性
    // 对于obj.__proto__来说:toString是它的私有属性

    // 也就是说一个属性是私有属性还是公有属性,还需要看它针对是谁。

    var arr = ["a","b"];
    console.dir(arr);
    console.log(arr.hasOwnProperty("length")); // true
    console.log(arr.hasOwnProperty("push")); // false
    console.log(arr.hasOwnProperty("__proto__")); // false
    console.log(arr.__proto__.hasOwnProperty("push")); // true

    // delete只能删除私有属性  不能删除公有属性
    delete arr[0];
    console.log(arr);
    delete arr.push;
    console.dir(arr)

    // 如果一个私有属性和公有属性重名了,私有属性会把公有属性覆盖掉
    var a1 = ["a"];
    console.dir(a1)
    a1.push("b")
    console.dir(a1)
    a1.push = function () {
        console.log("自己的push");
    }
    a1.push("c");
</script>
<script>
    // 判断一个属性是否属于某个对象
    // hasOwnProperty
    //  in  是一个运算符   是公有属性  得到的也是true
    var obj = {
        name:"wangcai"
    }
    console.log(obj.hasOwnProperty("name"));// 判断name是否是obj的私有属性  true
    console.log("name" in obj); // 判断name是否是obj的属性 true
    console.dir(obj)
    console.dir("toString" in obj) // 判断toString是否是obj的属性  true
    console.dir("xxx" in obj) // 判断xxx是否是obj的属性  false

</script>
可以查看一个属性是否是私有属性叫  hasOwnProperty()

七、对象是由函数创造的

在JS中,一个函数是有多个角色:
1)普通的函数
2)类 构造器
3)对象

1.普通的函数
<script>
    function f(){
        console.log("f...");
    }
    var g = new Function("a","b","return a + b");
    console.log(g(1,2));
</script>

Function():一个普通函数是由Function()创建的。

构造器
<script>
    function f(){

    }
    let f1 = new f();
    console.log(f1)
    console.log(typeof f1)
    console.log(f1 instanceof f)

</script>
对象
<script>
    var person={ 
        lassname:'human'
    }//将这个对象当做原型
    var p1 = Object.create(person)  //生成实例对象
    console.log(p1.classname)   //human,相当于p1.__proto__.classname
</script>

八、函数的四种

函数大约有四个角色:一个普通函数;在对象中可以当作一个方法;当作类,或者说是构造器;当成一个对象

1.角色一:一个普通的函数
<script>
    // 角色一:一个普通的函数
    function f() {
        console.log("f...")
    }
    // f();  作用1:让函数体执行    作用2:得到返回值
    f();
</script>
2. 角色2:在对象中可以当成一个方法
<script>
    // 角色2:在对象中可以当成一个方法
    let obj = {
        say:function () {  // 方法
            console.log("say...")
        },
        sleep:function () { // 方法
            console.log("sleep...")
        }
    }
    obj.say()
    obj.sleep()
</script>

3.角色3:类 构造器
<script>
    // 角色3:类  构造器
    function NBAPlayer() {

    }
    var nbaPlayer1 = new NBAPlayer();
    var nbaPlayer2 = new NBAPlayer();
    var nbaPlayer3 = new NBAPlayer();
    console.log(nbaPlayer1);
    console.log(nbaPlayer2);
    console.log(nbaPlayer3);
</script>
4.角色4:可以当作一个对象
<script>
    // 角色4:也可以当作是一个对象
    function F() {

    }
    F.name1 = "wangcai";
    F.age = 100
    console.log(F.name1)
    console.log(F.age)
</script>

九、让函数充当一个类

<script>
    function NBAPlayer() {

    }
    var p1 = new NBAPlayer();
    var p2 = new NBAPlayer();
    var p3 = new NBAPlayer();

    p1.name = "科比"
    p2.name = "乔丹"

    console.log(p1.name);
    console.log(p2.name);
</script>
<script>

    function NBAPlayer(name) {  // 类
        // console.log(this)
        this.name = name;
    }
    // new 运算符 肯定干几件事
    //    1)在构造器内部创建一个空对象
    //    2)让构造器中的this指向这个对象
    //    3)返回这个对象
    var p1 = new NBAPlayer("乔丹");
    var p2 = new NBAPlayer("科比");
    console.log(p1.name);
    console.log(p2.name);
</script>
<script>

    function NBAPlayer(name,age) {  // 类
        this.name = name;
        this.age = age;
    }
    var p1 = new NBAPlayer("乔丹",10);  //带入参数
    var p2 = new NBAPlayer("科比",20);
    console.log(p1.name);
    console.log(p1.age);
    console.log(p2.name);
    console.log(p2.age);
</script>
<script>
    function Go(name,age) {
        this.name = name;
        this.age = age;
    }
    var go = new Go("wc",100);
    console.log(window.go);  // {name: "wc", age: 100}
    console.log(window.name); // window上面本身就有一个name,输出值为window的值
    console.log(window.age);
</script>
<script>
    function F() {
        var a = 110;
        this.b = 1;
        this.c = 2;
        this.d = 3;
    }
    var f = new F();
    console.log(f); // {b: 1, c: 2, d: 3}
    //普通函数调用,函数里面的this指的是window里面的数据
    //变量a是局部变量,最后输出结果为 {b: 1, c: 2, d: 3}
</script>

<script>
    function F() {
        var a = 110;
        this.a = 1;
    }
    var f = new F();
    console.log(f); // { a:1 }
</script>
<script>
    function Fn(x) {
        let y = 20;
        this.total = x+y;
        this.say = function () {
            console.log(x+"+"+y+"="+this.total)
        }
    }
    let f1 = Fn(10);
    
    console.log(f1); // undefined 
                     //f1没有返回值,默认为undefined

    console.log(say());     //10 + 20 = 30 undefined内部函数无返回值
    console.log(total);     //30
    console.log(y);      //y is not defined 因为y是局部变量,在函数外部没有办法访问

    let f2 = new Fn(10);        //new 开辟了一个新空间
    f2.say();  // 10 + 20 = 30
    console.log(f2.total);  // 30
    
</script>

因为f2新开辟了一个空间,函数内部只存在say(),total

<script>
    function Fn(x) {
        let y = 20;
        this.total = x+y;
        this.say = function () {
            console.log(x+"+"+y+"="+this.total)
        }
    }
    let f2 = new Fn(10);
    console.log(f2.x);  // undefined
    console.log(f2.y);  // undefined
</script>

因为新开辟了新空间,内部为空,无法访问数据x,y

<script>
    function Fn(x) {
        let y = 20;
        this.total = x+y;
        this.say = function () {
            console.log(x+"+"+y+"="+this.total)
        }
    }
    let f1 = Fn(10);
    // cannot read property 'total' of undefined
    console.log(f1.total);
</script>

函数的返回值为空,无法指向变量名。会产生报错信息

<script>
    function Fn(x) {
        let y = 20;
        this.total = x+y;
        this.say = function () {
            console.log(x+"+"+y+"="+this.total)
        }
    }
    let f1 = new Fn(10);
    let f2 = new Fn(10);
    console.log(f1 == f2);  //false
</script>

f1与f2均开辟了新空间,且堆地址不同,所以输出结果为false

<script>
    function Fn(x) {
        let y = 20;
        this.total = x+y;
        this.say = function () {
            console.log(x+"+"+y+"="+this.total)
        }
    }
    let f1 = Fn(10);
    console.log(window.total);     //30
</script>

因为普通函数调用,函数里面的this指的是window,最终从GO里面找到数据,30。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值