JavaScript函数和对象

函数、对象

一. 目标

  • 使用arguments获取函数的所有参数 arguments是一个伪数组,可以暂且作为一个数组使用,也有参数,获取参数:实参的值赋值给形参

  • 预解析: 预解析就是程序执行代码之前会先解析,将变量名提到当前作用域的顶部,变量的值保留不变,函数整体提升到当前作用域的顶部,优先级是函数整体比变量名要优先提升到顶部,然后自上而下解析代码

  • 作用域和作用域链: 作用域分为:局部作用域----局部变量 全局作用域-----全局变量

  • 匿名函数和自调用函数

  • 对象的组成

  • 创建自定义构造函数和创建对象

  • new关键字的执行过程

  • 不同情况下this的指向

  • 遍历对象的成员和删除对象成员

  • 函数也是一种数据类型

二. 函数

2.1 函数体内的arguments

  • 思考

    写一个函数,实现计算用户输入任意个数字的总和 ?

  • arguments

    • arguments,在函数体内可以使用。arguments中存放了所有的实参。
    • arguments的使用:
    function getSum(){
     //arguments可以暂时看成是一个函数内部提供的数组,集合了所有的实参。
     //arguments.length;  参数的个数
     //arguments[下标];   //获取一个实参
     var sum = 0;
     for(var index = 0;index<arguments.length;index++){
     sum = sum + arguments[index];
     }
     return sum;
    }
    ​
    var result = getSum(10,20,30,40,50);
    alert(result);</pre>
    

2.2 预解析

  • 思考:

    • 思考1?:
    alert(a);  //报错</pre>
    
    • 思考2:
    /*
     对于js的执行顺序,默认是自上而下执行。
     对第一个alert(a)之前并没有创建变量。按道理应该报错。
    */
    alert(a);     //但是不会报错
    var a = 123;
    alert(a); </pre>
    
    • 思考3:
    fn();   //报错
    //函数表达式
    var fn = function(){
     alert(1);
    };</pre>
    
    • 思考4:
    fn(); //不报报错
    //函数声明
    function fn() {
     alert(1); 
    }</pre>
    
  • 什么是预解析

    ​ 程序准备→执行。程序在执行之前,有个预备过程。 预备过程要做的事就是预解析。预备过程要做两件事,分别是:

    • 把用var关键字所声明的变量名(仅仅是变量名),提升到当前执行环境的顶部。
    • 把用函数声明所创建的函数(函数整体),提升到当前执行环境的顶部。

2.3 作用域

  • 什么是作用域?

    作用域,指的是变量或函数调用的使用范围。

  • 全局作用域

    • 什么是全局作用域?
    > 函数之外的执行环境,就是全局作用域。
    
    • 全局变量
    > 在全局作用域中用var关键字所创建的变量,就是全局变量。
    > 
    > 全局变量的作用范围是程序中的任何地方。
    > 
    >
    > var a = 123;   //a是全局变量
    > function fn() {
    >  alert(a);   //123;
    > }
    > fn();
    > alert(a);  //123;</pre>
    
  • 局部作用域

    • 什么是局部作用域?
    > 函数体内的环境,就是局部作用域。
    
    • 局部变量
    > 在局部作用域中用var关键字所创建的变量,就是局部变量。局部变量的作用范围是,仅仅是本函数体内使用。
    > 
    >
    > function fn(){
    >  var a = 123;
    >  alert(a);
    > }
    > alert(a); //报错</pre>
    
    • 函数的形参可以看成是局部变量
    > 
    > function fn(a) {
    >  alert(a);
    > }
    > alert(a); //报错</pre>
    
  • 看预解析

    • 思考?
    > 
    > var a = 123;
    > function fn(){
    >  console.log(a);  //a的值 undefined;
    >  var a = 456;
    > }
    > fn();
    > console.log(a);   //a的值 123</pre>
    
    • 预解析中的变量提升,说是提升到当前执行环境的顶部。 当前执行环境指的是当前作用域。
    • 在局部作用域中使用一个变量时,若局部变量 和 全局变量重名时,在局部作用域中会优先使用局部变量。
  • 作用域链

    • 代码
    var a = 1;
    function fn1(){
     var a = 2;
     var b = '2b';
     function fn2(){
     var a = 3;
     function fn3(){
     var a = 4;
     console.log(a);   //a的值 ?
     consoe.log(b);    //b的值 ?
     }
     
     }
    }</pre>
    
      • 什么是作用域链?​ 当访问一个变量时,会先从本作用域中去找这个变量中去找,若找不到则向上一级作用域中去找,依次类推,就形成了一个作用域链。
  • JS中没有块级作用域

    • 什么是块级作用域
    > ​ 在其他编程语言中,如java、c#等,在if语句、循环语句中创建的变量,仅仅只能在本if语句、本循环语句中使用。如下Java代码
    > 
    >
    > if(true){
    >  int num = 123;
    >  system.out.print(num);  //123;
    > }
    > system.out.print(num); //报错</pre>
    
    • JS中没有块级作用域
    > JS中没有块级作用域【ES5版本之前】
    > 
    > 
    > if(true){
    >  var num = 123;
    >  console.log(123); //123
    > }
    > console.log(123);  //123;</pre>
    
    
    
    ​
    

2.4 匿名函数和自执行函数

  • 匿名函数

    匿名函数就是没有名字的函数。在js中匿名函数需要配合运算符使用。如:

    //匿名函数 常用
    (function(){
    alert(1);
    });

    //匿名函数
    !function(){
    alert(1);
    };

    //匿名函数
    -function(){
    alert(1);
    };</pre>

  • 自执行函数(自调用函数)

    自执行函数就是匿名函数创建后马上执行。

    //匿名函数 常用
    (function(){
    alert(1);
    })();

    //匿名函数
    !function(){
    alert(1);
    }();

    //匿名函数
    -function(){
    alert(1);
    }();</pre>

  • 匿名函数和自定义函数的优点

    • 可以模拟块级作用域
    • 可以避免全局变量污染​

三. 对象

3.1 为什么要学习对象

​ 后面的很多知识点都是通过对象调用出来的,所以我们必须务必知道对象组织数据的方式。

3.2 什么是对象

  • 对象的概念

    从两个层面理解:

    • 生活层面,对象是单个事物抽象出来的实例。
    > ​ “万物皆对象”,一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个与远程服务器的连接也可以是对象。当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。
    
    • 数据层面,对象是一个容器,封装了属性和方法。
    > *   对象是一种数据,属于引用类型的数据
    >     
    >     
    > *   属性:对象的静态特征。
    >     
    >     
    > *   方法:对象的动态特征。
    >     
    

3.3 对象的创建方式

  • 类和对象

    > 抽象出的模板。
    
    • 对象
    > 具体的实例。
    
    • 类和对象的关系
    > 类是对象的模板,对象是类的实例。对象需要通过类来创建:具体语法如下
    > 
    > 
    > var 对象名 = new 类名();</pre>
    > 
    > [图片上传失败...(image-907306-1516642285952)]
    
  • 方式一:通过Object类创建

    • Object 类是系统提供的一个类,可以直接使用。
    • 代码:
    var hero1 = new Object();  //空的对象,里面属性和方法
    //字面量创建
    //var hero1 = {};   //和new Object()性质一样,空的对象,里面属性和方法
    hero1.name = '孙悟空';
    hero1.age = 18;
    hero1.attack = function(){
     alert(this.name + '发动攻击...');
    }
    hero01.attack();</pre>
    
  • 方式二:通过自定义构造函数创建(自定义类)

    • 在es6之前,js中没有类的概念,但可以通过构造函数模拟。
    • 构造函数
    > 构造函数,可以用来创建并初始化对象。
    
    • 语法:
    //创建构造函数。和普通函数创建方式一样,当命名时首字母要大写(帕斯卡命名)
    function 函数名(参数1,参数2...){
     //this表示通过new创建的哪个当前的对象
     this.键 = 参数1;
     this.键 = 参数2;
     ...
    }
    ​
    //通过构造函数创建对像
    var 对象1 = new 函数名(实参1,实参2...);
     
    //new 关键字执行的过程
    ① 在函数体内创建一个空的对象(看不见)
    ② 让当前this指向这个空的对象
    ③ 通过this给当前空的对象添加键值对
    ④ 返回已经添加好所有键值对的对象给外面的变量。(看不见)</pre>
    
    • 代码:
    /*
     自定义构造函数(类) Hero
    */
    function Hero(name,age){
     this.name = name;
     this.age = age;
     this.sayHi = function(){
     console.log('我叫' + this.name + ',我今年' + this.age + '岁');
     }
     this.attack = function(){
     console.log(this.name + '发动攻击...')
     }
    }
    ​
    /*
     通过自定义构造函数创建对象
    */
    var wuKong = new Hero('孙悟空',18);
    wuKong.sayHi();
    wuKong.attack();
    ​
    var baJie = new Hero('猪八戒',20);
    baJie.sayHi();
    wuKong.attack();</pre>
    

3.4 对象的操作

  • 对象组织数据的方式:

    对象组织数据的方式是: 键值对。

    • 键,指的是属性名或方法名。
    • 值,指的是实际的数据。
  • 给对象增加属性和方法:

    • 对象名.键名 = 值;
    • 对象名['键名'] = 值;
    • 代码:
    var dog1 = {};
    dog1.name = '旺财'; //属性
    dog1['age'] = 1;    //属性
    dog1.call = function(){  //方法
     alert(this.name + '在汪汪叫...')
    }
    //注意,方法要用函数来表示</pre>
    
  • 访问对象中的属性和方法:

    • 对象.键名;
    • 对象[‘键名’];
    • 代码:
    var dog1 = {};
    dog1.name = '旺财'; //属性
    dog1['age'] = 1;    //属性
    dog1.call = function(){  //方法
     alert(this.name + '在汪汪叫...')
    }
    //注意,方法要用函数来表示
    dog1.call(); //调用
    console.log(dog1['name']);
    console.log(dog1.age);</pre>
    
  • 删除对象中的属性和方法:

    • delete 对象.键名;
    • delete 对象['键名'];
    • 代码:
    var dog1 = {
     name:'旺财',
     age:1,
     call:function(){
     alert(this.name + '在汪汪叫...')
     }
    };
    //删除之前访问
    console.log(do1.name); //旺财
    //删除
    delete dog1.name;
    //删除之后访问
    console.log(dog1.name); //undefiend
    //检测对中是否还要name属性
    console.log(dog1.hasOwnProperty('name'));  //false;</pre>
    
  • 检测一个对象中是否存在某个属性或方法:

    对象.hasOwnProperty('键名'); //返回boolean值,false表示不存在,true表示存在

  • 遍历对象中的键值对

    • 遍历方式 for-in
    for(var key in 对象){
     //key 是对象中的每一个键
     //对象[key]; 
    }</pre>
    
    • 代码
    var student1 = {
     name:'张三',
     age:17,
     gender:'男',
     scroe:100
    };
    for(var key in student1){
     console.log(student1[key]);
    }</pre>
    
  • 检测一个对象的数据类型

    • 对象是引用数据类型,检测对象时不要用typeof去检测,要用instanceof
    对象 instanceof 构造函数名;    //返回boolean值,true表示属于,false表示不属于</pre>
    
    • 代码
    /*
     创建构造函数 Person
    */
    function Person(name,age,gender){
     this.name = name;
     this.age = age;
     this.gender = gender;
    }
    // 创建一个Person类型的对象 p1
    var p1 = new Person('张三',17,'男');
    //检测对象p1是否属于Person
    console.log(p1 instanceof Person);  //true</pre>
    

3.5 this 指向问题

  • this 介绍

    this是一个关键字,这个关键字在程序执行时会指向不同的对象。也就是说这个this到底指向谁?得看程序的执行情况。</pre>

  • 构造函数和普通函数调用时,this指向不同的对象

    • this指向 window对象
    function Person(){
     this.name = '张三';
     console.log(this);   //window
    }
    // Person当做普通函数调用
    Person();</pre>
    
    • this指向被创建的实例对象
    function Person(){
     this.name = '张三';
     console.log(this);   //Person类型的一个实例对象
    }
    //Person当做构造函数调用
    var p1 = new Person();</pre>
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,093评论 0 13
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,703评论 2 17
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,434评论 0 5
  • 相信所有人都听过我要结婚了,“他人挺好的”、“他条件不错”、“他对我很好”、“他挣得挺多的”、“她可爱漂亮”...
    臆想豌豆阅读 222评论 0 0
  • 不知道是从什么时候开始,自己的脚步慢慢快了起来,仿佛只要停下来就会变的懈怠,变的失败。然而即便如此,也没有把自己的...
    PPU阅读 226评论 2 1