前端学习--day2

目录

什么是JavaScript

对象类型

1) Function


什么是JavaScript

它是一种脚本语言,可以用来更改页面内容,控制多媒体,制作图像、动画等等

例子

  • 修改页面内容

js 代码位置

例子

* 修改页面内容



js 代码位置

```html
<script>
	// js 代码
</script>
```

引入 js 脚本

```html
<script src="js脚本路径"></script>
```

* 注意,到了框架之后,引入方式会有不同

1. 变量与数据类型

1) let :star:


let 变量名 = 值;


* let 声明的变量可以被多次赋值,例如


let a = 100;  // 初始值是 100
a = 200;	  // ok, 被重新赋值为 200


2) const :star:

* const 修饰的叫常量,只能赋值一次


const b = 300; // 初始值是 300
b = 400;	   // error, 不能再次赋值


* const 并不意味着它引用的内容不可修改,例如

const c = [1,2,3];
c[2] = 4; 	        // ok, 数组内容被修改成 [1,2,4]
c = [5,6];			// error, 不能再次赋值


3) var

能用let尽量用let,因为var会有作用域的问题

var 声明的变量可以被多次赋值,例如
var f = 100;
f = 200;
### 基本类型

#### 1,2) undefined 和 null

* 执行表达式或函数,没有返回结果,出现 undefined
* 访问数组不存在的元素,访问对象不存在的属性,出现 undefined
* 定义变量,没有初始化,出现 undefined

例

```js
console.log(1);  	// 函数没有返回值, 结果是  undefined
let a = 10;		 	// 表达式没有返回值, 结果是 undefined
let b = [1,2,3];
console.log(b[10]); // 数组未定义元素是 undefined
let c = {"name":"张三"};
console.log(c.age); // 对象未定义属性是 undefined
let d;
console.log(d);		// 变量未初始化是 undefined
```

二者共同点

* 都没有属性、方法
* 二者合称 Nullish

二者区别

* undefined 由 js 产生
* null 由程序员提供



#### 3) string :star:

js 字符串三种写法

```js
let a = "hello";  // 双引号
let b = "world";  // 单引号
let c = `hello`;  // 反引号
```



html 代码如下,用 java 和 js 中的字符串如何表示?

```html
<a href="1.html">超链接</a>
```

java 显得比较繁琐

```java
String s1 = "<a href=\"1.html\">超链接</a>";

String s2 = """
    <a href="1.html">超链接</a>""";
```

js 就比较灵活

```js
let s1 = '<a href="1.html">超链接</a>';

let s2 = `<a href="1.html">超链接</a>`;
```



模板字符串(Template strings)

需求:拼接 URI 的请求参数,如

```
/test?name=zhang&age=18
/test?name=li&age=20
```

传统方法拼接

```js
let name = ; // zhang li ...
let age = ; // 18 20 ...

let uri = "/test?name=" + name + "&age=" + age;
```

模板字符串方式

```js
let name = ; // zhang li ...
let age = ; // 18 20 ...

let uri = `/test?name=${name}&age=${age}`;
```



#### 4,5) number 和 bigint:star:

number 类型标识的是双精度浮动小数,例如

```js
10 / 3;   // 结果 3.3333333333333335
```

既然是浮点小数,那么可以除零

```js
10 / 0;	  // 结果 Infinity 正无穷大
-10 / 0;  // 结果 -Infinity 负无穷大
```

浮点小数都有运算精度问题,例如

```js
2.0 - 1.1; // 结果 0.8999999999999999
```

字符串转数字

```js
parseInt("10"); 	// 结果是数字 10 
parseInt("10.5");	// 结果是数字 10, 去除了小数部分
parseInt("10") / 3; // 结果仍视为 number 浮点数, 因此结果为 3.3333333333333335

parseInt("abc");	// 转换失败,结果是特殊值 NaN (Not a Number)

字符串转换为整数,JavaScript会自动帮我们装欢
"10"-0
10

"10"+0
'100'
```

要表示真正的整数,需要用 bigint,数字的结尾用 n 表示它是一个 bigint 类型

```js
10n / 3n;			// 结果 3n, 按整数除法处理
```



#### 6) boolean :star:

* Truthy
* Falsy

在 js 中,并不是 boolean 才能用于条件判断,你可以在 if 语句中使用【数字】、【字符串】... 作为判断条件

```js
let b = 1;

if(b) { // true
    console.log("进入了");
}
```



这时就有一个规则,当需要条件判断时,这个值被当作 true 还是 false,当作 true 的值归类为 truthy,当作 false 的值归类为 falsy

下面值都是 falsy

* `false`
* `Nullish (null, undefined)`
* `0, 0n, NaN`
* ``` "" '' `` ```  即长度为零的字符串

剩余的值绝大部分都是 truthy

有几个容易被当作 falsy 实际是 truthy 的

* `"false", "0"` 即字符串的 false 和 字符串的零
* `[]` 空数组
* `{}` 空对象



#### 7) symbol

* 很少使用

对象类型

1) Function

 定义函数

function 函数名(参数) {
    // 函数体
    return 结果;
}

例

function add(a, b) {
    return a + b;
}


调用函数

函数名(实参);

例


add(1, 2);     // 返回 3


js 中的函数调用特点:对参数的**类型**和**个数**都没有限制,例如


add('a', 'b');  // 返回 ab
add(4, 5, 6);   // 返回 9, 第三个参数没有被用到, 不会报错
add(1);			// 返回 NaN, 这时 b 没有定义是 undefined, undefined 做数学运算结果就是 NaN




##### 默认参数

java 中(spring)要实现默认参数的效果得这么做:
@RestController 
public class MyController {
    
    @RequestMapping("/page")
    @ResponseBody
    public void page(
        @RequestParam(defaultValue="1") int page, 
        @RequestParam(defaultValue="10") int size
    ){
        // ...
    }
}


js

function pagination(page = 1, size = 10) {
    console.log(page, size);
}




##### 匿名函数

语法

(function (参数) {
    // 函数体
    return 结果;
})

例


(function(a,b){
    return a + b;
})


第一种场景:定义完毕后立刻调用


(function(a,b){
    return a + b;
})(1,2)


第二种场景:作为其它对象的方法,例如

页面有元素


<p id="p1">点我啊</p>


此元素有一个 onclick 方法,会在鼠标单击这个元素后被执行,onclick 方法刚开始是 null,需要赋值后才能使用


document.getElementById("p1").onclick = (function(){
    console.log("鼠标单击了...");
});




##### 箭头函数


(参数) => {
    // 函数体
    return 结果;
}


* 如果没有参数,() 还是要保留
* 如果只有一个参数,() 可以省略
* 如果函数体内只有一行代码,{} 可以省略
* 如果这一行代码就是结果,return 可以省略

例
document.getElementById("p1").onclick = () =>  console.log("aa");




##### 函数是对象

以下形式在 js 中非常常见!

1. 可以参与赋值,例,具名函数也能参与赋值


function abc() {
    console.log("bb");
}

document.getElementById("p1").onclick = abc;




2. 有属性、有方法,执行 `console.dir(abc)`,输出结果如下

ƒ abc()
    arguments: null
    caller: null
    length: 0
    name: "abc"
    ➡prototype: {constructor: ƒ}
    [[FunctionLocation]]: VM1962:1
    ➡[[Prototype]]: ƒ ()
    ➡[[Scopes]]: Scopes[1]


* 其中带有 f 标记的是方法,不带的是属性
* 带有 ➡ 符号的可以继续展开,限于篇幅省略了

* 带有 `[[ ]]` 的是内置属性,不能访问,只能查看
* 相对重要的是 `[[Prototype]]` 和 `[[Scopes]]` 会在后面继承和作用域时讲到



3. 可以作为方法参数


function a() {
    console.log('a')
}

function b(fn) {          // fn 将来可以是一个函数对象
    console.log('b')
    fn();                 // 调用函数对象
}

b(a)




4. 可以作为方法返回值


function c() {
    console.log("c");
    function d() {
        console.log("d");
    }
    return d;
}
c()()




##### 函数作用域

函数可以嵌套(js 代码中很常见,只是嵌套的形式更多是匿名函数,箭头函数)


function a() {
    function b() {        
    }
}

看下面的例子


function c() {
    var z = 30;
}

var x = 10;
function a() {
    var y = 20;
    function b() {
        // 看这里
        console.log(x, y);
    }
    b();
}
a();


* 以函数为分界线划定作用域,所有函数之外是全局作用域
* 查找变量时,由内向外查找
  * 在内层作用域找到变量,就会停止查找,不会再找外层
  * 所有作用域都找不到变量,报错
* 作用域本质上是函数对象的属性,可以通过 console.dir 来查看调试



##### 闭包


var x = 10;
function a() {
    var y = 20;
    function b() {
        console.log(x,y);
    }
    return b;
}
a()();  // 在外面执行了 b


* 函数定义时,它的作用域已经确定好了,因此无论函数将来去了哪,都能从它的作用域中找到当时那些变量
* 别被概念忽悠了,闭包就是指**函数能够访问自己的作用域中变量**



##### let、var 与作用域

如果函数外层引用的是 let 变量,那么外层普通的 {} 也会作为作用域边界,最外层的 let 也占一个 script 作用域

let x = 10; 
if(true) {
    let y = 20;
    function b() {
        console.log(x,y);
    }
    console.dir(b);
}


如果函数外层引用的是 var 变量,外层普通的 {} 不会视为边界


var x = 10; 
if(true) {
    var y = 20;
    function b() {
        console.log(x,y);
    }
    console.dir(b);
}

如果 var 变量出现了重名,则他俩会被视为同一作用域中的同一个变量


var e = 10; 
if(true) {
    var e = 20;
    console.log(e);	// 打印 20
}
console.log(e);		// 因为是同一个变量,还是打印 20


如果是 let,则视为两个作用域中的两个变量


let e = 10; 
if(true) {
    let e = 20;	
    console.log(e);	// 打印 20
}
console.log(e);		// 打印 10


要想里面的 e 和外面的 e 能区分开来,最简单的办法是改成 let,或者用函数来界定作用域范围


var e = 10; 
if(true) {
    function b() {
        var e = 20;
    	console.log(e);
    }
    b();
}
console.log(e);	


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值