首页 > 编程语言 >【九】JavaScript之对象

【九】JavaScript之对象

时间:2023-07-04 14:36:54浏览次数:55  
标签:console log 对象 JavaScript 作用域 num var 函数

【九】JavaScript之对象

【1】对象

  • js中,虽然是函数优先的编程语言,但是使用上也是基于对象的
    • 所以在js中也存在万物皆为对象的情况。

【2】对象的创建

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /**
     * 对象的创建
     */
    // 1. 通过字面量{}创建
    var xiaoming1 = {};   // 空对象
    var xiaoming2 = {     // 有属性有方法的对象
        age: 18,
        sex: true,
        desc(){
            console.log("js对象的方法");
            console.log(this.age, this.sex); // this表示当前对象
        }
    }
    console.log(xiaoming1);
    console.log(xiaoming2);
    // 对象的属性调用
    console.log(xiaoming2.age)
    // 对象的方法调用
    xiaoming2.desc()

    // 2. 通过系统对象Object来创建
    var xiaoming3 = new Object(); // 空对象
    var xiaoming4 = Object(); // 空对象
    // Object是javascript提供给开发者创建空对象使用的.
    // Object内部基本都是一些不对外开放的方法属性
    // Object是javascript内部的一切对象的基本对象[构造函数]
    console.log(xiaoming3);
    console.log(xiaoming4);

    // 3. 通过构造函数来创建对象
    function Humen(name="匿名对象",age=0){
        this.name = name;
        this.age  = age;
        this.say  = function(){
            console.log("我是Humen里面的代码");
        }
    }

    var xiaoming5 = new Humen("小明", 17);
    console.log(xiaoming5);


    //4. 通过类创建对象
    // 类名 后面必须跟着花括号,花括号内部就是类里面的代码
    // 原生js中的类只存在实例方法或实例属性,没有类属性或类方法
    class Person{
        // 构造函数,方法名必须叫constructor,等同于 python的类中的__init__方法
        constructor(name, age) {
            this.name = name;
            // 等同于python里面的 self.age = age
            this.age = age;
        }
        say(){
            // 对象的方法,将来在类被实例化的时候,可以让对象调用
            console.log(`我叫${this.name},我今年${this.age}岁!`)
        }
    }

    var xiaoming6 = new Person("小明",18)
    xiaoming6.say();

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

【3】对象的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var xiaoming = {     // 有属性有方法的对象
        age: 18,
        sex: true,
        desc(){
            console.log("js对象");
        }
    }

    // 可以给对象追加新属性或新方法,也可以针对原有的属性值或方法进行修改
    xiaoming.name = "小明";

    // 给对象追加方法,在对象的外部,追加方法,不能使用箭头函数
    xiaoming.say = function(){
        console.log(`我叫${this.name},我今年${this.age}岁!`);
    }

    console.log(xiaoming);

    // 访问对象的属性
    console.log(xiaoming.name);
    console.log(xiaoming.age);
    // 访问对象的方法
    xiaoming.say();

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

【4】this伪对象

  • 默认情况下,在对象的方法中,this代表的就是当前对象
    • 在函数或者函数外界,this代表的是当前页面的超全局对象。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        // 在函数外界,this就是window对象
        // console.log(this);
        // console.log(window);
        // console.log(this === window);

        // // 在对象的方法中,this代表的就是当前对象
        // class Humen{
        //     constructor(name, age) {
        //         this.name = name;
        //         this.age  = age;
        //     }
        //     say(){
        //         return `你好,我叫${this.name}!`
        //     }
        // }
        //
        // var xiaohong = new Humen("小红", 18);
        // console.log(xiaohong);
        // console.log( xiaohong.say() ); // // say是xiaohong的方法,所以this代表小红
        //
        // var xiaoming = new Humen("小明", 13);
        // console.log(xiaoming);
        // console.log( xiaoming.say() ); // // say是xiaoming的方法,所以this代表小明

        // 所以要看清楚,方法或函数在调用时,左边的变量是谁?

        var name = "window下的变量";

        function desc(){
            return this.name;
        }

        class Company{
            constructor(name) {
                this.name = name;
            }
        }

        var c = new Company("小明科技有限科技公司")
        c.desc = desc;
        console.log(c.desc()); // 小明科技有限科技公司

        class Person{
            constructor(name) {
                this.name = name;
            }
        }
        var p = new Person("张三丰");
        p.desc = desc;
        console.log( p.desc() );  // 张三丰
        console.log(p.desc === c.desc); // true


        // 请问这里会显示什么呢?
        console.log( desc() ); // desc调用时左边时没有任何的变量的,所以默认是window调用,因此在desc函数中,this代表的就是window对象


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

【5】函数或方法与作用域的问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // // js属于解释器语言,所以针对代码的运行实际上分了2个阶段:词法解析 与 代码执行。
    // // 普通函数与匿名函数除了在代码的运行阶段上分配空间的时间不一样以外,其他的操作都是一样的。
    // // 普通函数分配空间是在词法解析阶段分配的。
    // // 匿名函数分配空间是在代码执行阶段分配的。
    // function abc(){
    //     console.log("hello")
    // }
    // var func = abc  // 在js中实际上分2部执行的, 词法解析阶段先执行 var func; 代码执行阶段后执行 func = abc;
    // func();
    // abc();
    //
    //
    // // 箭头函数实际上并不是匿名函数的简写,而是一种特殊的匿名函数。
    // // 箭头函数分配空间也是在代码执行阶段分配的。
    // let fn = (a,b) => { // 箭头函数的参数列表,在只有一个形参的情况下, let fn = a => {}
    //     return a+b
    // }
    // console.log( fn(10,20) );
    //
    // // 简写效果:
    // let fn2 = (a,b) => a+b;  // 如果箭头函数的代码段中只有一行代码,可以省略return
    // console.log( fn2(10,20) );


    // // 三种函数实际上都可以作为函数的参数使用,在这种情况下,实际上就会存在一些细微的区别。
    // var arr1  = ['a', '1', '10', '102', 11,51,31,32,33,40, 'w', 'c']
    // // 1. 把普通函数作为参数传递
    // function fn(a,b){
    //     return a-b  // 正序
    //     // return b-a     // 倒序
    // }
    //
    // // 数组排序,按数字大小排序,忽略字母
    // arr1.sort(fn)
    // console.log(arr1);

    // // 2. 把普通匿名函数作为参数传递
    // var arr1  = ['a', '1', '10', '102', 11,51,31,32,33,40, 'w', 'c']
    // arr1.sort(function(a, b){
    //     // return a-b;
    //     return b-a;
    // })
    // console.log(arr1)


    // // 3. 把箭头函数作为参数传递
    // var arr1  = ['a', '1', '10', '102', 11,51,31,32,33,40, 'w', 'c']
    // arr1.sort((a, b)=>a-b); // 正序
    // // arr1.sort((a, b)=>b-a); // 倒序
    // console.log(arr1)


    /**
     * 箭头函数与匿名函数的区别
     */
    // // 案例1:
    // class Bloom{
    //     constructor(time) {
    //         this.time = time;
    //         this.t = null;
    //     }
    //     has_time(){
    //         // 倒计时功能
    //         if(this.time>0){
    //             clearInterval(this.t);
    //             // this.t = setInterval(function(){ // 匿名函数中,this代表的window,当前匿名函数实际上是被setInterval调用的,而setInterval实际上时window对象提供的,所以this代表的window对象
    //             this.t = setInterval(()=>{  // 箭头函数中,this.代表的是Bloom的实例对象,箭头函数会复刻父级作用域下的this
    //                 console.log(`this.time=${this.time}`, this);
    //                 this.time = this.time - 1;
    //                 if(this.time < 1){
    //                     console.log("爆炸!!!");
    //                 }
    //             }, 1000);
    //         }
    //     }
    // }
    //
    // var b = new Bloom(3600)
    // b.has_time()


    // // 案例2:
    // var xiaoming = {
    //     age: 18,
    //     name: "小明",
    // }
    //
    // // xiaoming.say = ()=>{ // 使用箭头函数,箭头函数会把父级作用域下的this复刻到函数内部,则this指向window对象      ===>   我叫,我今年undefined岁!
    // xiaoming.say = function(){ // 使用匿名函数,会把this指向调用当前方法的对象,则this当前对象   ===>   我叫小明,我今年18岁!
    //     console.log('this=',this);
    //     console.log(`我叫${this.name},我今年${this.age}岁!`);
    // }
    // console.log(xiaoming);
    // xiaoming.say();

    /**
     * 箭头函数与匿名函数在作用域上表现不同。
     * 匿名函数,会this指向到调用当前方法的对象,
     * 箭头函数,会把this指向到父级作用域上的this。
     */
    // js中的作用域分全局作用域与局部作用域。
    // 其中,函数外就属于全局作用域,而函数内就属于局部作用域。
    // 全局作用域下的变量,可以在任意位置上使用,叫全局变量,一旦定义以后,直到当前网页代码执行结束以后才会被浏览器回收。
    // 局部作用域下的变量,只能在当前函数中使用,叫局部变量,在函数运行时创建,函数运行结束以后被浏览器回收,下一次函数被调用,则会被再次创建。

    /**
     * 全局变量具有穿透性,可以直接在函数内部调用或修改值
     * @type {number}
     */
    // var num = 10; // 在函数外的变量可以直接使用到函数内部
    // function fn1(){
    //     console.log(num); // 10
    //     num = 20; // 对全局变量进行重新赋值
    //     function fn2(){
    //         console.log(num); // 20
    //     }
    //     fn2();
    // }
    // fn1();
    // console.log(num); // 20


    // var num = 10; // 在函数外的变量属于全局变量,但是当全局变量与局部变量一样时,函数内会优先使用局部变量
    // function fn1(){
    //     console.log(num); // undefined
    //     var num = 20; // 这句代码与上面的不一样的时,多了一个var关键字
    //     function fn2(){
    //         console.log(num); // 20
    //     }
    //     fn2();
    // }
    // fn1();
    // console.log(num); // 10


    // var num = 10; // 在函数外的变量属于全局变量,但是当全局变量与局部变量一样时,函数内会优先使用局部变量
    // function fn1(){
    //     console.log(num); // undefined
    //     // 这句代码与上面的不一样的是,var换成了let关键字,
    //     // let与var一样也是可以声明变量,但是不一样的是2点:
    //     //             1. let的作用域范围时花括号,var的作用域范围时函数
    //     //             2. 在局部作用域下,let关键字声明的变量,必须严格按照先声明后调用来执行的。
    //     let num = 20;
    //     function fn2(){
    //         console.log(num); // 20
    //     }
    //     fn2();
    // }
    // fn1();
    // console.log(num); // 10



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

【6】全局变量与局部变量的区别

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /**
     * js中的变量查找,是从内往外按作用域逐层查找的: 当前作用域->父级作用域->顶级作用域
     * 查找过程中,如果找到则取值,停止查找流程。如果直到顶级作用域下还是没有对应的变量,则报错。
     * 注意:js中,函数名、类名、变量名都是变量,最终在内存中存储的方式都是函数。
     *
     *
     */
     // var num = 0;
     // // 全局作用域[顶级作用域]
     // function fn1(){ // fn1作用域
     //     console.log(num); // 查找到当前作用域下,已经存在了num,只是没有赋值,所以是undefined
     //     var num = 10;
     //     function fn2(){ // fn2作用域,fn1是fn2的父级作用域
     //         let num = 20;
     //         console.log(num);
     //     }
     //     fn2();
     // }
     // fn1();

    // 面试题,一套非常坑人的题目
    function fn1(){
        // console.log(num);  // 为什么31与32存在时,31行会报错呢?因为32中的num没有使用var或者let,所以在词法阶段,根本没有分配到空间,也没有创建对应的变量。
        // num = 2;
        function fn2(){
            num = 2; // 此处num首次出现却不使用var声明时,这该变量会默认作为window对象的属性存在,js中调用window的属性或方法,是不需要写上window的。
            console.log(num); // 2
        }
        fn2();
        console.log(num); // 2
    }
    fn1();
    console.log(num); // 2

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

标签:console,log,对象,JavaScript,作用域,num,var,函数
From: https://www.cnblogs.com/dream-ze/p/17525627.html

相关文章

  • 【八】JavaScript之函数
    【八】JavaScript之函数【1】函数javascript被称为披着面向对象的皮的函数式编程语言,是函数优先的编程语言,所以本质上js中的一切都是基于函数构建出来,所以函数本身也是对象,也是一等公民。function,是类似变量一样的容器,代表了一段具有指定功能的代码段。【2】函数使用的......
  • 【七】JavaScript之异常判断
    【七】JavaScript之异常判断【1】异常捕获文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/try...catchjs中提供了三种异常处理的写法:try...catchtry...finallytry...catch...finallytry{//尝试执行的代码}catch(e){//......
  • 【六】JavaScript之流程控制
    【六】JavaScript之流程控制【1】语句块{//语句块,会作为一个整体来执行。}判断语句/分支语句idswitch循环语句/遍历语句【2】判断语句/分支语句【2.1】if语句//if中的条件的运算结果只会是布尔值if(条件){//条件结果为true执行这里的代码}if(......
  • 【十二】JavaScript之BOM
    【十二】JavaScript之BOM【1】什么是BOMBOM(BrowerObjectModel,浏览器对象模型),主要是浏览器中js解释器提供给开发者调用浏览器功能的对象或接口方法因为旧版本浏览器厂商实现不一样,所以有可能存在同一段代码在不同旧浏览器下的结果不一致的兼容问题。当然现代浏览器几乎......
  • 【十一】JavaScript之案例-todolist
    【十一】JavaScript之案例-todolist基本页面<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><style>body,ul,input{margin:0;padding:......
  • 【十四】JavaScript之DOM中的事件操作
    【十四】JavaScript之DOM中的事件操作【1】事件操作所谓的事件(Event),其实就是用户与浏览器之间的一次交互过程或交互行为。例如:用户输入一段内容,用户鼠标晃动一下等等。js中提供了大量的事件操作给开发者,在用户发生事件操作以后,进行反馈,响应。事件类型有很多,但是操......
  • 【十三】JavaScript之DOM
    【十三】JavaScript之DOM【1】DOMDOM(DocumentObjectModel,译作文档对象模型),这部分内容主要是学习document对象提供给开发者操作html/xml文档的方法属性或子对象来完成动态特效的。当然这部分代码在不同浏览器下的效果几乎一样,除了IE。元素操作[元素的获取,元素的属性......
  • web开发基础笔录(5)-Javascript(1)
    目录概述概述JavaScript(简称“JS”)是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式。......
  • 初学者:8个JavaScript技巧
    有很多方法可以优化我们的JavaScript代码,本文总结了我在工作中经常使用的8个JavaScript技巧,希望它也能帮助你。减少使用if-else在编写两个以上的if...else时,是否有更好的优化方法?如下代码,我们需要根据一个汉堡包的名字来计算它的价格。constgetPriceByName=(na......
  • JavaScript中的if与switch的区别是什么?
    很多同学问我if和swicth的区别,今天我就从多个维度来和大家分析一下if与switch的区别到底是什么?1.语法结构:if语句:使用if关键字后接条件表达式,如果条件为真,则执行if块中的代码。switch语句:使用switch关键字后接一个表达式,根据表达式的值匹配相应的case标签,并执行对应的代码块。2.可读......