从0开始学web-day36-js进阶06

18 篇文章 0 订阅

1.复习
day36-js05复习
2.原型推导过程

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    // 定义类
    function People(name, age, sex) {
        // 数据
        this.name = name;
        this.age = age;
        this.sex = sex;

        // 提交方法
        // 如果赋值的是一个匿名函数 会在每一次实例化的对象的时候都开辟一个新的内存空间 这样的话就造成资源浪费

        // 于是希望对其改造
        this.say = People.obj.say;

        // 继续添加其它的方法
        this.sayHello = People.obj.sayHello;


    }

    // 提取并声明函数
    // function say() {
    //     console.log('你好, 我的名字叫做' + this.name + ' 我的年龄是' + this.age + '岁 我是一个' + this.sex + '孩子' );
    // }

    // function sayHello() {
    //     console.log('hello');
    // }

    // 现在的问题是: 如果在构造函数体中每定义一个方法 就要在全局中声明一个函数 造成全局作用域的污染

    // 我们希望把多个全局变量压缩成为一个 
        // 创建一个对象 让该对象去承担所有的变量

    // var obj = {
    //     say: function() {
    //         console.log('你好, 我的名字叫做' + this.name + ' 我的年龄是' + this.age + '岁 我是一个' + this.sex + '孩子' );
    //     },

    //     sayHello: function() {
    //         console.log('hello');
    //     }
    // }

    // 现在希望一个变量也不要存在 并且不要影响方法的使用
        // 可以将该对象放入到构造函数的命名空间下
    People.obj = {
        say: function() {
            console.log('你好, 我的名字叫做' + this.name + ' 我的年龄是' + this.age + '岁 我是一个' + this.sex + '孩子' );
        },

        sayHello: function() {
            console.log('hello');
        }
    }


    // 实例化对象
    var xiaoming = new People('xiaoming', 12, '男');
    var xiaohong = new People('xiaohong', 11, '女');
    xiaoming.say();
    xiaohong.say();
    // 测试小明和小红调用的方法是否是同一个
    console.log(xiaoming.say === xiaohong.say);
    </script>
</body>
</html>

3.原型

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    /**
     * 原型: prototype
     *  该属性是每一个函数天生拥有的属性 值是一个对象 对象中天生拥有一个constructor属性 值是构造函数本身
     *  该属性对于普通函数来说 没什么用
     *  但是对于构造函数来说 
     *      -此时每new一次的得到的实例化对象 都会有一个隐含的属性 __proto__属性 访问到构造函数的原型
     * 
     *  作用: 实例共享数据
     *  
     *  原型就好比是公共区域 在原型中添加的所有数据 都可以被每一个实例化对象所共享的
     * 
     *  以后要添加方法的时候 一定给类的原型添加 这样的话可以避免在全局创建多余的变量 并且还可以让每一个实例化对象共享数据
     * 
     * 
     **/
    // 定义类
    function People(name, age, sex) {
        // 数据
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    // 将方法写在原型中
    People.prototype.say = function() {
        console.log('你好, 我的名字叫做' + this.name + ' 我的年龄是' + this.age + '岁 我是一个' + this.sex + '孩子' );
    }

    People.prototype.sayHello = function() {
        console.log('hello');
    }


    // 输出原型对象
    // console.log(People.prototype);

    // 实例化对象
    var xiaoming = new People('xiaoming', 12, 'nan');
    var xiaohong = new People('xiaohong', 11, 'nv');
    // 每一个实例化对象 天生可以调用类原型中的数据
    xiaoming.say();
    xiaohong.say();
    console.log(xiaoming.say === xiaohong.say);

    console.log(xiaoming);


    // 对象身上是没有prototype属性
    // console.log(xiaoming.prototype);
    // 但是每一个实例化对象身上都可以访问__proto__属性 间接的访问到构造函数的原型
    // console.log(xiaoming.__proto__ === People.prototype);


    // 每一个对象都有一个__proto__属性 找到的都是该对象的构造函数原型
    // var obj = {};
    // console.log({}.__proto__);

    </script>
</body>
</html>

4.原型拓展

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    // 定义类
    function People(name, age, sex) {
        // 数据
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    // 将方法写在原型中
    People.prototype.say = function() {
        console.log('你好, 我的名字叫做' + this.name + ' 我的年龄是' + this.age + '岁 我是一个' + this.sex + '孩子' );
    }

    People.prototype.sayHello = function() {
        console.log('hello');
    }

    // 在原型中添加一个属性
    People.prototype.msg = 'hello'; 


    // 实例化对象
    var xiaoming = new People('xiaoming', 12, 'nan');
    var xiaohong = new People('xiaohong', 11, 'nv');


    // 检测xiaoming是否是People的实例 可以利用instanceof检测
    // console.log(xiaoming instanceof People);
    // console.log(xiaohong instanceof People);


    // instanceof 会查找整个原型链 
    // 该关键字查找的规则是: 查看右侧构造函数的原型是否出现在了左边对象的原型链中
    // console.log(xiaoming instanceof Object);
    // console.log({} instanceof Object);


    // 内置构造函数
    // console.log(Object.prototype);
    // var obj = {};
    // var obj2 = new Object();





    // in: 
	// 	该操作符检测某个对象身上是否包含了指定的属性 
    // console.log('name' in xiaoming);
    // console.log('age' in xiaoming);
    // console.log('sex' in xiaoming);
    // // (会查找整个原型)
    // console.log('msg' in xiaoming);

	// hasOwnProperty:
	// 	该方法检测某个对象身上是否包含了指定的属性
    // console.log(xiaoming.hasOwnProperty('name'));
    // console.log(xiaoming.hasOwnProperty('age'));
    // console.log(xiaoming.hasOwnProperty('sex'));
    // 不会去原型中查找数据
    // console.log(xiaoming.hasOwnProperty('msg'));


    // 接下来做一个有趣的测试
    // console.log(xiaoming.hasOwnProperty('hasOwnProperty'));
    // console.log(xiaoming.__proto__.hasOwnProperty('hasOwnProperty'));
    // 该方法是在Object.prototype {}
    // console.log(xiaoming.__proto__.__proto__.hasOwnProperty('hasOwnProperty'));


    // 只要是一个对象就有原型对象
    // console.log(xiaoming.__proto__);
    // console.log(xiaoming.__proto__.__proto__);
    // console.log(xiaoming.__proto__.__proto__.__proto__);



    /***
     * 想要熟知原型必须掌握以下几点:
     *  1 所有的引用类型都可以任意拓展数据
     *  2 所有的对象都有一个隐式的原型 (__proto__)
     *  3 所有的构造函数都一个显示的原型 (prototype)
     *  4 每一个对象通过__proto__ 找到的永远是构造函数的原型对象
     *  5 从一个对象身上开始使用一个数据的时候 先从对象自身开始查找 如果有则使用 如果没有 会去到原型中查找  如果找到则使用 如果没有找到 会继续往原型的原型中查找 
     *  直到找到Object.prototype  最终会得到undefined  这样一层一层网上查找的过程就是一个链式查找 也称为原型链的查找
     * 
     **/


    </script>
</body>
</html>

5.原型链的图解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    // 内置构造函数 创建对象
    // console.log(Object.prototype);

    // 内置构造函数 Function 创建函数  原型对象是一个函数
    // console.log(Function.prototype); //  ƒ () { [native code] }
    // console.log(Function.prototype.__proto__); // Object.prototype
    // console.log(Function.__proto__); // ƒ () { [native code] }


    // 结论:
        // 所有的对象都是Object的实例
        // 所有的函数都是Function的实例
        // 函数也是对象


    console.log(Object instanceof Function);    // true
    console.log(Function instanceof Function);  // true
    console.log(Function instanceof Object);    // true
    console.log(Object instanceof Object);      // true
    </script>
</body>
</html>

6.安全类

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    // // 创建对象的方式
    // var obj = {};
    // // 构造函数
    // var obj1 = new Object();
    // // 工厂函数
    // var obj2 = Object();
    // console.log(obj, obj1, obj2);

    // // 内置构造函数 Array 创建数组的
    // var arr = [];
    // var arr1 = new Array();
    // var arr2 = Array();
    // console.log(arr, arr1, arr2);



    // // 定义类
    // function People(name, age, sex) {
    //     this.name = name;
    //     this.age = age;
    //     this.sex = sex;

    //     console.log(111, this);
    // } 

    // // 创建实例化对象 使用new
    // var xiaoming = new People('xiaoming', 12, 'nan');
    // // 创建实例化对象 不使用new
    // // 如果外部没有使用new 来调用 也就说明作为普通函数调用 并且this指向的是window 所以所有的数据都给了window
    // var xiaohong = People('xiaohong', 11, 'nv');
    // // console.log(window.name);
    // // console.log(window.age);
    // // console.log(window.sex);

    // console.log(xiaoming);
    // console.log(xiaohong);



    // 改造:
        // 利用函数体中的this做判断 
       // 定义类
    function People(name, age, sex) {
        // 最简单的方式就是判断this是否指向window
        // if (this === window) {
        //     // 说明作为普通函数调用 必须出现return
        //     return new People(name, age, sex);
        // } else {
        //     this.name = name;
        //     this.age = age;
        //     this.sex = sex;
        // }

        // 利用instanceof关键字做判断
        if (this instanceof People) {console.log(1);
            this.name = name;
            this.age = age;
            this.sex = sex;
        } else {console.log(2);
            // 说明没有通过new
            return new People(name, age, sex);
        }
    } 

    // 创建实例化对象 使用new
    var xiaoming = new People('xiaoming', 12, 'nan');
    // 创建实例化对象 不使用new
    var xiaohong = People('xiaohong', 11, 'nv');

    // console.log(xiaoming);
    console.log(xiaohong);
    </script>
</body>
</html>

7.内置构造函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    // 内置构造函数的分类:
	// ECMAScript核心语法也支持一些内置构造函数:
	    // Object  Array  Function  String  Number  Boolean  RegExp  Error  Date 

    // 浏览器中也支持内置构造函数 : Image
    // 之前创建图片元素
    // var img = document.createElement('img');
    // 现在的创建方式
    // var img = new Image();
    // console.log(img);



    // Function该内置构造函数用于创建函数
	// 使用方式:new Function(arg1, arg2, ......, body);
	// 	可以接收多个参数,除了最后一个参数是函数体,其它的都是形参
    // var fn = new Function('a', 'b', 'return a + b')(1, 2);
    // console.log(fn);

    // json对象字符串
    // var json = '{ "msg": "hello", "title": "nihao" }';

    // 可以利用Function将其转为真正的对象
    // 注意: return后面有空格
    // var obj = new Function('return ' + json);
    // console.log(obj);


    // 特点:通过new Function得到的函数,通过函数.name属性得到的是anonymous
		// 而通过函数表达式和函数声明式,打点调用name属性得到的是函数名称
    // console.log(obj.name);

    // function demo() {}
    // console.log(demo.name);

    // var demo1 = function() {}
    // console.log(demo1.name);


    // 拓展:
	// 函数.length 得到的是 形参的个数
	// arguments.length 得到的是 实参的个数

    function demo(arg, arg1) {
        // console.log(arguments.length);

        // arguments.callee 指向了函数本身
        console.log(arguments.callee);
    }

    // console.log(demo.length);
    // 执行函数
    demo(100, true, 'abc');



    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值