JavaScript 4—对象

基本操作

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            JS中数据类型
                String字符串
                Number数值
                Boolean布尔值
                Null空值
                Undefined未定义
                    以上这五种类型属于基本数据类型,以后我们看到的值
                        只要不是上边的5种,全都是对象
                Object对象

            基本数据类型都是单一-的值"hello" 123 true,
                值和值之间没有任何的联系。
            在JS中来表示一个人的信息(name gender age)
            var name = "孙悟空";
            var gender = "男";
            var age = 18;
            如果使用基本数据类型的数据,我们所创建的变量都是独立,不能成为一个整体。
            对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。

            对象的分类:
            1.内建对象
                由ES标准中定义的对象,在任何的ES的实现中都可以使用
                比如: Math String Number Boolean Function object... .
            2.宿主对象
                由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
                比如BOM DOM
            3.自定义对家
                由开发人员自己创建的对象
        */

        //创建对象
        /*
            使用new关键字调用的函数,是构造函数constructor
            构造函数是专门用来创建对象的函数
            使用typeof检查一个对象时,会返回object

        */
        var obj = new Object();

        // console.log(typeof obj);
        // console.log(obj);

        /*
            在对象中保存的值称为属性
            向对象添加属性
            语法:对象.属性名=属性值;

        */
        //向obj中添加一个name属性
        obj.name = "孙悟空";
        //向obj中添加一个gender属性
        obj.gender = "";
        //向obj中添加一个age属性
        obj.age = 18;
        console.log(obj);

        /*
            读取对象中的属性
                语法:对象.属性名
            如果读取对象中没有的属性,不会报错而是会返回undefined
        */
        console.log(obj.name);
        /*
            修改对象的属性值
            语法:对象.属性名=新值
        */
        obj.name = "齐天大圣";
        console.log(obj.name);

        /*
            删除对象的属性
            语法: delete 对象.属性名
        */
        delete obj.name;
        console.log(obj.name);

        /*
        属性名
            对象的属性名不强制要求遵守标识符的规范
                什么乱七八糟的名字都可以使用
            但是我们使用是还是尽量按照标识符的规范去做

        如果要使用特殊的属性名,不能采用.的方式来操作
        需要使用另一种方式:
            语法:对象["属性名"] = 属性值
        读取时也需要采用这种方式
            
        使用[]这种形式去操作属性,更加的灵活
            在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
        */
        obj["123"] = 789;
        var n = "123";
        console.log(obj["123"]);
        console.log(obj[n]);

        /*
            属性值
                JS对象的属性值,可以是任意的数据类型
                    甚至也可以是一个对象

        */
        //创建一个对象
        var obj2 = new Object();
        obj2.name = "猪八戒";

        //将obj2设置为obj的属性
        obj.test = obj2;
        console.log(obj.test.name);
        /*
        in运算符
            通过该运算符可以检查- -个对象中是否含有指定的属性
                如果有则返回true,没有则返回false
            语法:
                "属性名" in 对象
        */
        //检查obj中是否含有test2属性
        console.log("test" in obj);

    </script>
</head>

<body>
</body>

</html>

基本数据类型和引用数据类型

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            基本数据类型
                String Number Boolean Null Undefined
            引用数据类型
                Object

            JS中的变量都是保存到栈内存中的,
                基本数据类型的值直接在栈内存中存储,
                值与值之间是独立存在,修改-个变量不会影响其他的变量
                
                对象是保存到堆内存中的,每创建一个新的对象, 就会在堆内存中开辟出一一个新的空间,
                而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一一个对象引用,
                当一个通过一个变量修改属性时,另一个也会受到影响

        */

        var a = 123;
        var b = a;
        a++;
        console.log("a = " + a);
        console.log("b = " + b);

        var obj = new Object();
        obj.name = "孙悟空 ";
        var obj2 = obj;
        obj.name = "猪八戒";
        console.log(obj.name);
        console.log(obj2.name);

        //设置obj2为null
        obj2 = null;
        /*console.1og(obj);
        console.1og(obj2);*/
        var c = 10;
        var d = 10;
        //console.log(c == d);
        var obj3 = new Object();
        var obj4 = new Object();
        obj3.name = "沙和尚";
        obj4.name = "沙和尚 "
        console.log(obj3);
        console.log(obj4);
        console.log(obj3 == obj4);
        /*
            当比较两个基本数据类型的值时,就是比较值
            而比较两个引用数据类型时,它是比较的对象的内存地址,
            如果两个对象是一摸一样的,但是地址不同,它也会返回false
        */
    </script>
</head>

<body>
</body>

</html>

 对象字面量

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //创建一个对象
        //var obj = new Object();
        /*
            使用对象字面量来创建一个对象
        */
        var obj = {};
        //console.1og(typeof obj);
        obj.name = "孙悟空";
        console.log(obj.name);
        /*
            使用对象字面量,可以在创建对象时,直接指定对象中的属性
            语法: {属性名:属性值,属性名:属性值....}
            对象字面量的属性名可以加引号也可以不加,建议不加
            如果要使用一些特殊的名字,则必须加引号

            属性名和属性值是一组一-组的名值对结构,
                名和值之间使用:连接,多个名值对之间使用,隔开
                如果一个属性之后没有其他的属性了,就不要写,

        */
        var obj2 = {
            name: "猪八戒",
            age: 28,
            gender: "",
            test: { name: "沙和尚" }
        };
        console.log(obj2);

    </script>
</head>

<body>
</body>

</html>

 函数对象

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            函数
                函数也是一个对象
                函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
                函数中可以保存一些代码在需要的时候调用
                使用typeof检查-一个函数对象时,会返回function

        */

        //我们在实际开发中很少使用构造函数来创建一个函数对象
        //创建一个函数对象
        // var fun = new Function();
        // console.log(typeof fun);
        //可以将要封装的代码以字符串的形式传递给构造函数
        // var fun1 = new Function("console.log('Hello这是我的第一一个函数');");
        //封装到函数中的代码不会立即执行
        //函数中的代码会在函数调用的时候执行
        //调用函数语法:函数对象()
        //当调用函数时,函数中封装的代码会按照顺序执行
        // fun1();

        /*
            使用函数声明来创建一个函数
            语法: 
            function函数名( [ 形参1 ,形参2 ... 形参N ] )
        */

        function fun2() {
            console.log("这是我的第二个函数~~~");
            alert("哈哈哈哈哈");
            document.write("~~~~(>_<)~~~~");
        }
        //console.1og(fun2);
        //调用fun2
        fun2();

        /*
            使用函数表达式来创建一个函数
            var 函数名 = function( [形参1 ,形参2.. .形参N] ){
                语句... .
            }
        */
        var fun3 = function () {
            console.log("我是匿名函数中封装的代码");
        }
        fun3();
        /*
            定义一个用来求两个数和的函数
                可以在函数的( )中来指定一个或多 个形参(形式参数)
                多个形参之间使用,隔开,声明形参就相当于在函数内部声明了对应的变量
                但是并不赋值
        */
        function sum(a, b) {
            console.log(a + b);
        }
        /*
            在调用函数时,可以在()中指定实参(实际参数)
            实参将会赋值给函数中对应的形参
        */
        //sum(1,2);
        sum(123, 456);
        /*
            调用函数时解析器不会检查实参的类型,
                所以要注意,是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型的检查
            函数的实参可以是任意的数据类型
        */
        sum(123, "hello");
        sum(true, false);
        /*
            调用函数时,解析器也不会检查实参的数量
                多余实参不会被赋值
            如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
        */
        sum(123, 456, "hello", true, nul1);


        /*
            可以使用return来设置函数的返回值
            语法:
                return值
            return后的值将会会作为函数的执行结果返回,
            可以定义一个变量,来接收该结果
            在函数中return后的语句都不会执行
            如果return语句后不跟任何值就相当于返回一个undefined,
            如果函数中不写return,则也会返undefined

            return后可以跟任意类型的值
        */

        //调用函数
        //变量result的值就是函数的执行结果
        //函数返回什么result的值就是什么
        function sum(a, b, c) {
            //alert(a + b +c);
            vard = a + b + C;
            return d;
            alert("hello");
        }
        var result = sum(4, 7, 8);
        console.log("result =" + result);

    </script>
</head>

<body>
</body>

</html>

 函数实参可以是任意值

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //定义一个函数,判断-一个数字是否是偶数,如果是返回true,否则返回false
        function isOu(num) {
            // if (num % 2 == 0) {
            //     return true;
            // } else {
            //     return false;
            // }
            return num % 2 == 0;
        }
        var result = isOu(15);
        console.log("result = " + result);

        //定义一个函数,可以根据半径计算一个圆的面积, 并返回计算结果
        function mianji(r) {
            return 3.14 * r * r;
        }
        result = mianji(10);
        console.log("result = " + result);

        /*
            创建一个函数,可以在控制台中输出-一个人的信息
            可以输出人的name age gender address

            实参可以是任意的数据类型,也可以是一个对象
                当我们的参数过多时,可以将参数封装到一个对象,然后通过对象传递
        */
        // function sayHello(name, age, gender, address) {
        //     console.log("我是" + name + " ,今年我" + age + "岁了," + "我是一个" + gender + "人" + "我住在" + address);
        // }
        // sayHello("孙悟空", 18, "男", "花果山");
        function sayHello(o) {
            console.log("我是" + o.name + " ,今年我" + o.age + "岁了," + "我是一个" + o.gender + "" + "我住在" + o.address);
        }
        var obj = {
            name: "孙悟空",
            age: 18,
            gender: "",
            address: "花果山"
        }
        sayHello(obj);

        //实参可以是一个对象,也可以是一个函数

        function fun(a) {
            console.log("a = " + a);
        }
        fun(sayHello);

        fun(mianji(10));
        fun(mianji);
        /*
            mianji()
                调用函数
                相当于使用的函数的返回值
            mianji
                函数对象
            相当于直接使用函数对象
        */

    </script>
</head>

<body>
</body>

</html>

 函数返回值可以是任意值

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        function fun() {
            alert("函数要执行了~~~~");
            for (var i = 0; i < 5; i++) {
                console.log(i);
                if (i == 2) {
                    //使用break可以退出当前的循环
                    //break;
                    //continue用于跳过当次循环
                    //continue ;
                    //使用return可以结束整个函数
                    neturn;
                }
            }
            alert("函数执行完了~~~~");
        }
        fun();

        /*
            返回值可以是任意的数据类型
                也可以是一个对象,也可以是一个函数
        */
        function fun2() {
            return 10;
        }
        var a = fun2();
        console.log("a = " + a);

        function fun3() {
            //在函数内部再声明一-个函数
            function fun4() {
                alert("我是fun4");
            }
            //将fun4函数对象作为返回值返回
            return fun4;
        }
        a = fun3();
        console.log(a);

    </script>
</head>

<body>
</body>

</html>

 立即执行函数

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //函数对象()
        /*
            立即执行函数
            函数定义完,立即被调用,这种函数叫做立即执行函数
            立即执行函数往往只会执行一次
        */
        (function () {
            alert("我是一个匿名函数~~~");
        })();

        (function (a, b) {
            console.log("a = " + a);
            console.log("b = " + b);
        })(123, 456);

    </script>
</head>

<body>
</body>

</html>

 调用函数与调用方法

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //创建一个对象
        var obj = new Object();
        //向对象中添加属性
        obj.name = "孙悟空";
        obj.age = 18;
        //对象的属性值可以是任何的数据类型,也可以是个函数
        obj.sayName = function () {
            console.log(obj.name);
        };
        function fun() {
            console.log(obj.name);
        };
        //console.1og(obj . sayName);
        //调方法
        obj.sayName();
        //调函数
        fun();
        /*
            函数也可以称为对象的属性,
            如果一个函数作为一个对象的属性保存,
            那么我们称这个函数时这个对象的方法
            调用这个函数就说调用对象的方法(method)
            但是它只是名称上的区别没有其他的区别
        */

    </script>
</head>

<body>
</body>

</html>

 枚举对象中的属性

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //枚举对象中的属性
        //使用for ... in语句
        /*
            语法:
            for(var变量in对象){

            }

            for ... in语句对象中有几个属性,循环体就会执行几次
                每次执行时,会将对象中的一个属性的名字赋值给变量

        */
        var obj = {
            name: "孙悟空",
            age: 18,
            gender: "",
            address: "花果山"
        };

        for (var n in obj) {
            console.log("属性名:" + n + " 属性值:" + obj[n]);
        }

    </script>
</head>

<body>
</body>

</html>

 作用域

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            作用域
                作用域指一个变量的作用的范围
                在JS中一共有两种作用域:
                1.全局作用域
                    直接编写在scri pt标签中的IS代码,都在全局作用域
                    全局作用域在页面打开时创建,在页面关闭时销毁
                    在全局作用域中有一个全局对象window,我们可以直接使用
                    在全局作用域中有一个全局对象window,
                        它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
                    在全局作用域中:
                        创建的变量都会作为window对象的属性保存
                        全局作用域中的变量都是全局变量,
                            在页面的任意的部分都可以访问的到

                2.函数作用域
                    调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
                    每调用一次函数就会创建一个新的函数作用域, 他们之间是互相独立的
                    在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量
                        在全局作用域中无法访问到函数作用域的变量
                    当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有就先上一级中寻找直到全局作用域,如果全局作用域中没有,则报错

                    在函数作用域也有声明提前的特性,
                        使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
                        函数声明也会在函数中所有的代码执行之前执行
        */
        var a = 10;
        var b = 20;
        //var c = "hello";
        // console.log(window.c);//undifined
        // console.log(c);//报错

        // window.alert("hello");
        // alert("hello");

        /*
            变量的声明提前
                使用var关键字声明的变量,会在所有的代码执行之前被声明
                    但是如果声明变量时不适用var关键字,则变量不会被声明提前

            函数的声明提前
                使用函数声明形式创建的函数function函数( ){ }
                    它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
                使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
        */
        console.log("a = " + a);
        var a = 123;

        // fun();//不报错
        // fun2();//报错

        //函数声明,会被提前创建
        function fun() {
            console.log("我是一个fun函数");
        }
        //函数表达式,不会被提前创建
        var fun2 = function () {
            console.log("我是fun2函数");
        };


        //创建一个变量
        var a = 10;
        function fun() {
            var a = "我是函数中的变量a";
            console.log("a = " + a);
        }
        fun();

        function fun3() {
            console.log(a);
            var a = 35;
        }
        fun3();

        //在函数中,不适用var声明的变量都会成为全局变量
        var c = 33;
        function fun5() {
            console.log("c = " + c);
            c = 10;
            d = 100;
        }
        fun5();
        //在全局输出c
        console.log("c =" + c);
        //在全局输出d
        console.log("d =" + d);

        // 定义形参就相当于在函数作用域中声明了变量
        var e = 23;
        function fun6(e) {
            alert(e);
        }
        fun6();
    </script>
</head>

<body>
</body>

</html>

 this

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
             这个隐含的参数就是this,this指向的是一个对象,
             这个对象我们称为函数执行的上下文对象,
             根据函数的调用方式的不同,this会指向不同的对象
                1.以函数的形式调用时,this永远都是window
                2.以方法的形式调用时,this就是调用方法的那个对象
        */
        function fun(a, b) {
            //console.log("a = "+a+", b="+b);
            console.log(this);
        }
        // fun();//window...

        //创建一个对象
        var obj = {
            name: "孙悟空",
            sayName: fun
        };
        //console.log(obj.sayName == fun);

        //以方法的形式调用,this是调用方法的对象
        obj.sayName();

        //以函数形式调用,this是window
        fun();


        //创建一个name变量
        var name = "全局";
        //创建一个fun()函数
        function fun() {
            console.log(this.name);
        }
        //创建两个对象
        var obj = {
            name: "孙悟空",
            sayName: fun
        };
        var obj2 = {
            name: "沙和尚",
            sayName: fun
        };
        fun();
        obj.sayName();
        obj2.sayName();
    </script>
</head>

<body>
</body>

</html>

arguements

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            在调用函数时,浏览器每次都会传递进两个隐含的参数:
                1.函数的上下文对象this
                2.封装实参的对象arguments
                    arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
                    在调用函数时,我们所传递的实参都会在arguments中保存
                arguments.length可以用来获取实参的长度
                我们即使不定义形参,也可以通过arguments来使用实参,
                    只不过比较麻烦
                    arguments[0]表示第一个实参
                    arguments[1]表示第二个实参 。。。
                它里边有一个属性叫做callee,
                    这个属性对应一个函数对象,就是当前正在指向的函数的对象


        */
        function fun() {
            //console.log(arguments instanceof Array);
            // console.log(Array.isArray(arguments));
            // console.log(arguments);
            // console.log(arguments.length);
            console.log(arguments.callee == fun);
        }
        fun("hello,true");

    </script>
</head>

<body>
</body>

</html>

 

call和apply

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        function fun(a, b) {
            // alert("我是fun函数! ");
            // alert(this);
            console.log("a = " + a);
            console.log("b = " + b);
        }
        /*
            call()和apply()
                这两个方法都是函数对 象的方法,需要通过函数对象来调用
                当对函数调用call( )和apply ( )都会调用函数执行
                在调用call和apply( )可以讲一个对象指定为第一个参数
                    此时这个对象将会成为函数执行时的this
                call()方法可以将实参在对象之后依次传递
                app1y()方法需要将实参封装到一个数组中统一传递

            this的情况:
                1.以函数形式调用时,this永远都是window
                2.以方法的形式调用时,this是调用方法的对象
                3.以构造函数的形式调用时,this是新创建的那个对象
                4.使用call和app1y调用时,this是指定的那个对象
        */

        var obj = {
            name: "obj",
            sayName: function () {
                alert(this.name);
            }
        };

        var obj2 = {
            name: "obj2",
        };

        /*fun.apply();
        fun.call();
        fun();*/
        // fun.apply(obj);//Object
        // fun.call(obj);//Object
        // fun();//window

        // obj.sayName.apply(obj2);//obj2

        fun.call(obj, 2, 3);
        fun.apply(obj, [2, 3]);
    </script>
</head>

<body>
</body>

</html>

 

使用工厂方法创建对象

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        //创建一个对象
        var obj1 = {
            name: "孙悟空",
            age: 18,
            gender: "",
            sayName: function () {
                alert(this.name);
            }
        };

        /*
            使用工厂方法创建对象
            通过该方法可以大批量的创建对象
        */
        function createPerson(name, age, gender) {
            //创建一个新的对象
            var obj = new Object();
            //向对象中添加属性
            obj.name = name;
            obj.age = age;
            obj.gender = gender;
            obj.sayName = function () {
                alert(this.name);
            }
            //将新的对象返回
            return obj;
        }
        var obj2 = createPerson("猪八戒", 28, "");
        var obj3 = createPerson("白骨精", 18, "");
        var obj4 = createPerson("蜘蛛精", 16, "");

        obj4.sayName();

        /*
            使用工厂方法创建的对象,使用的构造函数都是0bject
                所以创建的对象都是Object这个类型,
                就导致我们无法区分出多种不同类型的对象
        */
        //用来创建狗的对象
        function createDog(name, age) {
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            obj.sayHello = function () {
                alert("汪汪~~");
            };
            return obj;
        }
        //创建一个狗的对象
        var dog = createDog("旺财", 3);
        dog.sayHello();

        console.log(dog);
        console.log(obj4);
    </script>
</head>

<body>
</body>

</html>

 构造函数

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            创建一个构造函数,专门用来创建Person对象的
                构造函数就是一个普通的函数,创建方式和普通函数没有区别,
                不同的是构造函数习惯上首字母大写

            构造函数和普通函数的区别就是调用方式的不同
                普通函数是直接调用,而构造函数需要使用new关键字来调用

            构造函数的执行流程:
                1.立刻创建一个新的对象
                2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
                3.逐行执行函数中的代码
                4.将新建的对象作为返回值返回

            使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为-一个类
                我们将通过一个构造函数创建的对象,称为是该类的实例

            this的情况:
                1.当以函数的形式调用时,this是window 
                2.当以方法的形式调用时,谁调用方法this就是谁
                3.当以构造函数的形式调用时,this就是新创建的那个对象


            在Person构造函数中,为每一一个对象都添加了一个sayName方法,
                目前我们的方法是在构造函数内部创建的,
                    也就是构造函数每执行一次就会创建一个新的sayName
                也是所有实例的sayName都是唯一-的。
                这样就导致了构造函数执行一次就会创建一个新的方法,
                    执行10000次就会创建10000个新的方法,而10000个方法都是一摸一样的
                    这是完全没有必要,完全可以使所有的对象共享同一个方法
        */

        function Person(name, age, gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
            //向对象中添加一一个方法
            this.sayName = fun;
        }

        /*
            将sayName方法在全局作用域中定义
            
            将函数定义在全局作用域,污染了全局作用域的命名空间
                而且定义在全局作用域中也很不安全

            


        */
        function fun() {
            alert("Hello大家好,我是:" + this.name);
        };

        var per = new Person("孙悟空", 18, "");
        var per2 = new Person("猪八戒", 28, "");
        var per3 = new Person("白骨精", 18, "");
        var per4 = new Person("蜘蛛精", 16, "");

        function Dog() {

        }
        var dog = new Dog();

        console.log(per);
        console.log(dog);

        /*
            使用instanceof可以检查一个对象是否是一个类的实例
            语法:
                对象 instanceof 构造函数
                如果是,则返回true,否则返回false
            所有的对象都是Object的后代,
                所以任何对象和Object左instanceof检查时都会返回true
        */
        console.log(per instanceof Person);
        console.log(dog instanceof Person);

        console.log(per instanceof Object);
        console.log(dog instanceof Object);

    </script>
</head>

<body>
</body>

</html>

 原型

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
        原型prototype
            我们所创建的每一个函数, 解析器都会向函数中添加一个属性prototype
                这个属性对应着一个对象,这个对象就是我们所谓的原型对象
        如果函数作为普通函数调用prototype没有任可作用
        当函数以构造函数的形式调用时,它所创建的对象中都会有-一个隐含的属性,
            指向该构造函数的原型对象,我们可以通过__ proto__ 来访问该属性
        
        原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
            我们可以将对象中共有的内容,统一设置到原型对象中
        
        当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
            如果没有则会去原型对象中寻找,如果找到则直接使用
        
        以后我们创建构造函数时,可以将这些对象共有的属性和方法,统-添加到构造函数的原型对象中,
            这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
        */
        function Person() {
        }
        function MyClass() {
        }
        //向MyClass的原型中添加一一个方法
        MyClass.prototype.sayHello = function () {
            alert("hello");
        }

        MyClass.prototype.a = 123;
        // console.log(MyClass.prototype == Person.prototype);
        var mc = new MyClass();
        var mc2 = new MyClass();
        // console.log(mc.__proto__ == MyClass.prototype);
        //向mc中添加a属性
        mc.a = "我是mc中的a";
        console.log(mc2.a);
        mc.sayHello();


        //创建一个构造函数
        function MyClass() {
        }
        //向MyClass的原型中添加一个name属性
        MyClass.prototype.name = "我是原型中的名字";

        //console.log(mc. name);

        //使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
        //console.log("name" in mc);

        //可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性

        console.log(mc.hasOwnProperty("name"));
        console.log(mc.hasOwnProperty("hasOwnProperty"));
        /*
            原型对象也是对象,所以它也有原型,
            当我们使用一个对象的属性或方法时,会现在自身中寻找,
            自身中如果有,则直接使用,
            如果没有则去原型对象中寻找,如果原型对象中与,则使用,
            如果没有则去原型的原型中寻找,直到找到Object对象的原型,
            Object对象的原型没有原型,如果在0bject中依然没有找到,则返回undefined
        */
        console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));
        console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
        console.log(mc.__proto__.__proto__.__proto__);//null
    </script>
</head>

<body>
</body>

</html>

toString

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        function Person(name, age, gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
        }
        //创建一个Person实例
        var per = new Person("孙悟空", 18, "");
        //当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值
        //如果我们希望在输出对象时不输出[object Object], 可以为对象添加一-个toString个)方法
        // per.toString = function () {
        //     return "我是一个快乐的小Personl";
        // };

        //修改Person原型的toString
        Person.prototype.toString = function () {
            return "Person[name=" + this.name + ",age=" + this.age + ",gender=" + this.gender;
        }




        var result = per.toString();
        // console.log("result = " + result);
        console.log(per);
        // console.log(per.hasOwnProperty("toString"));//false
        // console.log(per.__proto__.hasOwnProperty("toString"));//false
        // console.log(per.__proto__.__proto__.hasOwnProperty("toString"));//true

    </script>
</head>

<body>
</body>

</html>

 垃圾清理

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        /*
            垃圾回收(GC)
                就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
                    这些垃圾积攒过多以后,会导致程序运行的速度过慢,
                    所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
            当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
                此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
                所以这种垃圾必须进行清理。
            在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
                我们不需要也不能进行垃圾回收的操作
            我们需要做的只是要将不再使用的对象设置null即可
        */
        var obj = new Object();
        //对对象进行各种操作
        obj=null;
    </script>
</head>

<body>
</body>

</html>

 

posted @ 2020-07-25 09:47  我等着你  阅读(159)  评论(0)    收藏  举报