【前端三剑客三】JavaScript的手术刀剖析第二篇

一、函数

浦东就是上海,上海就是浦东

  函数是什么?函数在Java中被称为方法。因此说,函数就是方法,方法就是函数。但是也有一些细微差别。

二者是同一个东西,但有不同的马甲
通常情况下,不去考量这两个概念的区别.但是如果非要考量,可以这样理解:

  • 函数,是和“对象"独立开来的代码片段.
  • 方法,是依托于对象的代码片段.方法=>成员函数
    在Java中,由于本身这样的代码片段都是依托于类和对象的.因此Java中都是称为"方法"。

1.语法格式

/ 创建函数/函数声明/函数定义
function 函数名(形参列表) {
	函数体
	return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
  • 不需要写返回值类型,
  • 形参列表中,不需要写形参类型

示例一:函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次

<script>
        function hello(){
            console.log("hello");
        }
        hello();
    </script>
  • 调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
  • 函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)

2.参数个数

实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配。

(1)示例一: 如果实参个数比形参个数少, 则此时多出来的形参值为 undefined

    <script>
        function add(a,b,c,d,e,f,g){
            return a + b + c + d + e + f + g;
        }
        console.log(add(10,20));
        console.log(add(10,20,30));
        console.log(add(10,20,30,40));
    </script>

在这里插入图片描述

  如果这里想要正常打印,需要加一个判断,就是a是否没被定义到,如果是,则置为0;

 <script>
        function add(a,b,c,d,e,f,g){
            a = a||0;
            b = b||0;
            c = c||0;
            d = d||0;
            e = e||0
            f = f||0;
            g = g||0;
            return a + b + c + d + e + f + g;
        }
        console.log(add(10,20));
        console.log(add(10,20,30));
        console.log(add(10,20,30,40));
    </script>

那么,此时就可以正常打印了。
在这里插入图片描述


(2)示例二:如果实参个数比形参个数多, 则多出的参数不参与函数运算

<script>
        function add(a,b){
            a = a||0;
            b = b||0;
            return a + b ;
        }
        console.log(add(10,20));
        console.log(add(10,20,30));
        console.log(add(10,20,30,40));
    </script>

可以看到,虽然你传过来的参数很多,但我形参只有两个,只能算两个实参的数据,多出来的不管。
在这里插入图片描述



  如果我们想拼接字符串,那怎么办?

  如果你想让你的代码,既能支持数字相加,又能支持字符串相加,这个时候就少不了要判定了.
  判定第一个参数,是字符串还是数字.(JS, typeof),通过第一个参数的类型,来决定后续参数的默认值,是0.还是"" 。


3.函数表达式

  在JavaScript中,函数是一等公民。函数,就像一个普通的变量一样,可以被赋值给其他的变量.也可以作为另一个函数的参数,还可以作为另一个函数的返回值…

  函数和普通的变量,并没有本质区别,但是函数这样的变量相比于普通变量多了个功能,就是可调用。


  函数表达式是什么?

函数表达式就是把一个函数赋值给一个变量。

<script>
        function hello(){
            console.log('hello');
        }
        let f = hello;
		//console.log(typeof f);//通过这行语句就可以查看f的类型
        //通过f就可以调用上面的函数
        f();
    </script>

在这里插入图片描述
上面的写法也可以变为:

 let f = function hello(){
 console.log('hello');
 }

还有可以变为以下:

let f = function(){
    console.log('hello');
}

  此时定义了一个没有名字的函数,称为"匿名函数",这还有另一个名字, lambda 表达式.而形如 function() { } 这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示.后面就可以通过这个 f变量来调用函数了


4.作用域

作用域指的是某个标识符名字在代码中的有效范围.

在 ES6 标准之前, 作用域主要分成两个

  1. 全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
  2. 局部作用域/函数作用域: 在函数内部生效.
    <script>
        let num = 10;
        console.log(num);

        function test1(){
            //局部变量
            let num =20;
            console.log(num);
        }

        function test2(){
            //局部变量
            let num =30;
            console.log(num);
        }

        test1();
        test2();
        console.log(num);
    </script>

在这里插入图片描述

创建变量时如果不写 var或者let, 则得到一个全局变量,如:

<script>
        function test(){
            num =20;
            console.log(num);
        }
        test();
        console.log(num);
    </script>

在这里插入图片描述


5.作用域链

  • 函数可以定义在函数内部
  • 内层函数可以访问外层函数的局部变量
<script>
        let num = 10;
        function hello(){
            function hello1(){
                console.log(num);
            }
            hello1();
        }
        hello();
    </script>

  JS中的作用域,是支持"逐级向上"查找的,上面代码当前是在hello1这个函数里,尝试打印num.但是在hello1 中,没有num变量。于是就往上级找,找到了hello函数这里,但是在hello里,也没有num,于是继续往上找,找到了全局作用域.找到了num,如果最后的全局作用域也没找到,就会报错。


二、对象

1.基本概念

对象是指一个具体的事物,“书本” 不是对象, 而是一个泛指的类别. 而 “我的书本” 就是一个对象

  在 JavaScript中, 字符串, 数值, 数组, 函数都是对象.每个对象中包含若干的属性和方法.

  • 属性: 事物的特征.
  • 方法: 事物的行为.

  假如你的有一只宠物狗,狗的体重,身高这些都是属性,而它会捡东西,会唱歌这些都是方法。

  对象需要保存的属性有多个, 虽然数组也能用于保存多个数据, 但是不够好。例如表示一个学生信息. (姓名蔡徐坤, 身高 175cm, 体重 170斤)。var student = [‘蔡徐坤’, 175, 170];但是这种情况下到底 175 和 170 谁表示身高, 谁表示体重, 就容易分不清。


  与Java中对象的区别:

  • 在Java中,对象,需要先有类,然后针对类的实例化才产生对象。Java中,类可以视为是一种自定义的类型.(Cat类和Dog类两个不同的类型)
  • JavaScript中,对象是不依托于类的,在JavaScript中所有的对象,都是一个类型. object

2.使用字面量创建对象 [常用]

使用 { } 创建对象
 let student = {
            name: '烦啦烦啦',
            age: 25,
            height: 175,
            weight: 124,

            speak:function(){
                console.log("嘴贱");
            },
            sing: function(){
                console.log("东北民谣")
            },
        };
  • 使用 { } 创建对象
  • 属性和方法使用键值对的形式来组织.
  • 键值对之间使用 , 分割. 最后一个属性后面的 , 可有可无
  • 键和值之间使用 : 分割.
  • 方法的值是一个匿名函数

使用对象的属性和方法:

//1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
        console.log(student.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号   
        console.log(student['age']);
// 3. 调用方法, 别忘记加上 ()     
        student.speak();

在这里插入图片描述


3. 使用 new Object 创建对象

 <script>
        let student = new Object();
        student.name = "死啦死啦";
        student.height = 175;
        student['weight'] = 140;
        student.sing = function(){
            console.log("各地歌曲");
        }

        console.log(student.name);
        console.log(student['weight']);
        student.sing();
    </script>
  • 使用 { } 创建的对象也可以随时使用 student.name = “蔡徐坤”; 这样的方式来新增属性

在这里插入图片描述


4.使用构造函数创建对象

  当前咱们所说的构造函数,其实是一种特殊的函数为了批量的创建出一组类似的对象.

基本语法:

function 构造函数名(形参) {
this.属性 =;
this.方法 = function...
}
var obj = new 构造函数名(实参);
  • 在构造函数内部使用 this 关键字来表示当前正在构建的对象,当看到函数内部,通过this.这样的方式来创建属性的时候,此时这个函数大概率就是构造函数了

  • 构造函数的函数名首字母一般是大写的.

  • 构造函数的函数名可以是名词.

  • 构造函数不需要 return

  • 创建对象的时候必须使用 new 关键字.

实例:使用构造函数重新创建猫咪对象

    <script>
        function Cat(name,type,sound){
            this.name = name;
            this.type = type;
            this.miao = function(){
                console.log(sound);
            }
        }

        var mimi = new Cat('咪咪','中华田园猫','喵')
        var xiaohei = new Cat('小黑', '波斯喵', '猫呜');
        var ciqiu = new Cat('刺球', '金渐层', '咕噜噜');

        console.log(mimi);
        mimi.miao;
    </script>

在这里插入图片描述


5.理解 new 关键字

new 的执行过程:

  1. 先在内存中创建一个空的对象 { }
  2. this 指向刚才的空对象(将上一步的对象作为 this 的上下文)
  3. 执行构造函数的代码, 给对象创建属性和方法
  4. 返回这个对象 (构造函数本身不需要 return, 由 new 代劳了)

6.JavaScript 的对象和 Java 的对象的区别

(1) JavaScript 没有 “类” 的概念

  对象其实就是 “属性” + “方法” . 类相当于把一些具有共性的对象的属性和方法单独提取了出来, 相当于一个 “月饼模子”.
   在JavaScript 中的 “构造函数” 也能起到类似的效果. 而且即使不是用构造函数, 也可以随时的通过 { } 的方式指定出一些对象 在
  ES6 中也引入了 class 关键字, 就能按照类似于 Java 的方式创建类和对象了.

(2)JavaScript 对象不区分 “属性” 和 “方法”

JavaScript 中的函数是 “一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行.

(3)JavaScript 对象没有 private / public 等访问控制机制

对象中的属性都可以被外界随意访问.

(4)JavaScript 对象没有 “继承”

  继承本质就是 “让两个对象建立关联”. 或者说是让一个对象能够重用另一个对象的属性/方法. JavaScript 中使用 “原型” 机制实现类似的效果

(5)JavaScript 没有 “多态”

  多态的本质在于 “程序猿不必关注具体的类型, 就能使用其中的某个方法”.,
C++ / Java等静态类型的语言对于类型的约束和校验比较严格。因此通过子类继承父类, 并重写父类的方 法的方式 来实现多态的效果. 但是在JavaScript 中本身就支持动态类型, 程序猿在使用对象的某个方法的时候本身也不需要对对象的 类型做出明确区分。
  因此并不需要在语法层面上支持多态。

举个例子:

在 Java 中已经学过 ArrayList 和 LinkedList. 为了让程序猿使用方便, 往往写作:

List<String> list = new ArrayList<>()

然后我们可以写一个方法:

void add(List<String> list, String s) {
	list.add(s);
}

我们不必关注 list 是 ArrayList 还是 LinkedList, 只要是 List 就行. 因为 List 内部带有 add 方法.
而当我们使用 JavaScript 的代码的时候:

function add(list, s) {
	list.add(s)
}

  add 对于 list 这个参数的类型本身就没有任何限制. 只需要 list 这个对象有 add 方法即可。 就不必像 Java 那样先继承再重写绕一个圈子。

三、了解WebAPI

1.什么是 WebAPI

JavaScript分成三大部分:

  • ECMAScript: 基础语法部分
  • DOM API: 操作页面结构
  • BOM API: 操作浏览器

WebAPI 就包含了 DOM + BOM

  如果要写一个更加复杂的有交互式的页面, 不仅需要基础语法,还需要 WebAPI 的支持。


2.API是什么

API 是一个更广义的概念. 而 WebAPI 是一个更具体的概念, 特指DOM+BOM。所谓的 API 本质上就是一些现成的函数/对象, 让程序猿拿来就用, 方便开发。

API就相当于一个工具箱. 只不过程序猿用的工具箱数目繁多, 功能复杂。

API 参考文档:API 参考文档


3.了解DOM

3.1.DOM是什么

DOM 全称为 Document Object Model.

W3C 标准给我们提供了一系列的函数, 让我们可以操作:

  • 网页内容
  • 网页结构
  • 网页样式

页面结构形如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>示例页面</title>
</head>
<body>
	<h2>这是一个示例页面</h2>
	<p id="p" title="this is p.">这是一个段落内容.</p>
</body>
</html>

DOM 树结构如下:

在这里插入图片描述

在这里一些重要的,我们需要了解的概念:

  • 文档: 一个页面就是一个 文档, 使用 document 表示.
  • 元素: 页面中所有的标签都称为 元素. 使用 element 表示.
  • 节点: 网页中所有的内容都可以称为 节点(标签节点, 注释节点, 文本节点, 属性节点等). 使用 node表示。

这些文档等概念在 JS 代码中就对应一个个的对象,所以才叫 “文档对象模型”。


四、获取元素

  获取元素.使用DOM的基础。要想操作页面上的元素,就需要先拿到对应的JS对象。DOM中提供了一组API能够获取到网页的元素。这里只介绍两个最重要的:querySelector和querySelectorAll。

1.querySelector

  这里获取元素类似于 CSS 选择器的功能,使用 querySelector 能够完全复用前面学过的 CSS 选择器知识, 达到更快捷更精准的方式获取到元素对象.

通过以下方式来进行获取:

var element = document.querySelector(selectors);

解析:

  • document这样的对象的属性.是页面中的全局对象。一个页面加载好了,就会自动生成一个全局变量,就叫做document .这里面就有一些属性和方法,让我们来操作页面的内容.

  • selectors 包含一个或多个要匹配的选择器的 DOM字符串 DOMString 。 该字符串必须是有效的

  • CSS选择器字符串;如果不是,则引发 SYNTAX_ERR 异常
    表示文档中与指定的一组CSS选择器匹配的第一个元素的 html元素 Element 对象.

  • 如果您需要与指定选择器匹配的所有元素的列表,则应该使用 querySelectorAll()

  • 可以在任何元素上调用,不仅仅是 document。 调用这个方法的元素将作为本次查找的根元素

正因为参数是选择器, 所以一定要通过特殊符号指定是哪种选择器,如下面例子的 .box 是类选择器, #star 是 id 选择器 等.

<script>
        let elem1 = document.querySelector('.box');
        console.log(elem1);
        let elem2 = document.querySelector('#id');
        console.log(elem2);
        let elem3 = document.querySelector('h3 span input');
        console.log(elem3);
    </script>

    <div class="box">abc</div>
    <div id = "id">123</div>
    <h3>
        <span>
            <input type="text" name="" id="">
        </span>
    </h3>

在这里插入图片描述


2.querySelectorAll

<div>
        <ul>
            <li>aaa</li>
            <li>bbb</li>
            <li>ccc</li>
            <li>ddd</li>
        </ul>
    </div>
    <script>
        let obj = document.querySelectorAll('ul li');
        console.log(obj);
    </script>

在这里插入图片描述
  准确的说, querySelectorAll返回的不是一个真正的原生数组.而是一个对象.只不过这个对象,有length,也能够通过下标的方式来访问内部元素,这样的对象使用起来和数组非常相似(一模一样),称为“伪数组"。


五、最后的话

  最近嗜睡,同时也终于快把人类简史看完了,这本真的是陆陆续续看了一年了,心不静,看书看一两页就倦了。最近感觉,也没心静,偶尔会有没意义之感,所以想在书中找寻些意义。

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十叶知秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值