【狂神说Java】阶段二笔记4. JavaScript-01

3 JavaScript

3.1 什么是JavaScript

JavaScript(行为):是一种弱类型脚本语言,其源代码不需经过编译,而是由浏览器解释运行,用于控制网页的行为,是一门世界上最流行的脚本语言

一个合格的后端人员,必须要精通JavaScript

ECMAScript可以理解为是JavaSctipt的一个标准,最新版本已经到es6版本,但是大部分浏览器还只停留在支持es5代码上!导致开发环境和线上环境版本不一致

3.2 快速入门

3.2.1 引入JavaScript

  1. 内部标签
<script>
    //......
</script>
  1. 外部引入

abs.js

//...

test.html

<script src="abc.js"></script>
  • 测试
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!--script标签内,写javascript代码-->
    <script>
        alert('hello, world');
    </script>

    <!--外部引入:注意,script标签必须成对出现-->
    <script src="js/qj.js"></script>

    <!--不用显示定义type,也默认就是javascript-->
    <script type="text/javascript"></script>
</head>
<body>

<!--这里也可以存放JavaScript代码-->
</body>
</html>

3.2.2 基本语法入门

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
        // 1.定义变量 变量类型 变量名 = 变量值;
        var score = 60;
        var name = "qinjiang";
        'helloworld'
        alert(score);

        // 2.条件控制
        if (score > 60 && score < 70){
            alert("60~70");
        }else if (score > 70 && score < 80){
            alert("70~80");
        }else{
            alert("other");
        }

        /*JavaScript严格区分大小写
          console.log(score) 在浏览器的控制台打印变量!System.out.println();
         */
    </script>

</head>
<body>
</body>
</html>

3.2.3 数据类型

数值,文本,图形,音频,视频…

  1. 变量
var $A_a = 1
  1. number:js不区分小数和整数,统一用number
123  // 整数
123.1  // 浮点数
1.23e3  //科学计数法
-99  //负数
NaN  //not a number
Infinity  //无限大
  1. 字符串
'abc'
"abc"
  1. 布尔值:true,false

  2. 逻辑运算

&&  // 两个都为真,结果为真
    
||  // 一个为真,结果为真// 真即假,假即真
  1. 比较运算符(重要)
=
==  // 等于(类型不一样,值一样,也会判断为true)
=== // 绝对等于(类型一样,值一样,结果为true)

​ 这是一个js的缺陷,坚持不要使用==比较

须知:NaN == NaN,这个与所有的数值都不想等,包括自己,只能通过isNaN(NaN)来判断

  • 浮点数问题:尽量避免使用浮点数进行运算,存在精度问题
console.log((1/3) === (1-2/3))
Math.abs(1/3-(1-2/3) < 0.00000000001)
  1. null 和 undefined

    null空

    undefined未定义

  2. 数组

Java的数组必须是相同类型的对象,js中不需要这样

var arr = [1, 2, 3, 4, 5, 'hello', null, true];  // 常用
new Array(1, 12, 3, 4, 5, 'hello');

数组下标如果越界了,就会报错

underfined
  1. 对象

对象是大括号,数组是中括号

对象的每个属性之间使用逗号隔开,最后一个不需要添加符号

// Person person = new Person(1, 2, 3, 4, 5);
var person = {
    name: 'qinjiang',
    age: 3,
    tags: ['js', 'java', 'web', '...']
}

取对象的值

person.name
> "qinjiang"
person.age
> 3

3.2.4 严格检查格式

<!--前提:IDEA需要支持ES6语法
'use strict'; 严格检查模式,预防js的随意性导致产生的一些问题
必须写在js的第一行-->
<script>
    'use strict';
    var j = 1;
    // ES6 let 局部变量都建议使用let定义
    let i = 1;
</script>

3.3 数据类型

3.3.1 字符串

  1. 正常字符串我们使用 ’ ’ 或者 " " 包裹
  2. 注意注意字符 \
\'
\n  //换行
\t  //table
\u4e2d  //中 \u#### Unicode字符
\x41  // Ascll字符
  1. 多行字符串编写
//tab上esc下的paio键~
let msg = `hello
world
你好啊!
`;
  1. 模拟字符串
let name = "qinjiang";
let msg1 = `你好呀,${name}`
console.log(msg1)
  1. 字符串长度
console.log(str.length);
  1. 字符串的不可变性

在这里插入图片描述

  1. 大小写转换
//注意,这里是方法,不是属性
student.toUpperCase()
student.toLowerCase()
  1. 获取指定下标
student.indexOf('u')
  1. substring
student.substring(1)  // tudent, 从第一个截取到最后一个字符
student.substring(1, 3)  // tu, [1, 3)

3.3.2 数组

Array可以包含任意的数据类型

  1. 长度
arr.length

注意:加入给arr.length赋值,数组长度就会发生变化,如果赋值过小,元素就会丢失

arr.length = 10
arr
> (10) []

arr[7]
> undefined

arr.length = 2
arr
> (2) []
  1. indexof,通过元素获得下标索引
arr.indexOf(2)
1

字符串的 “1” 和数字 1 是不同的

  1. slice() 可以截取Array的一部分,返回一个新数组,类似于String中的substring

  2. push()、pop() 尾部

push  //压入到数组尾部
pop  //弹出数组尾部的一个元素
  1. unshift()、shift() 头部
unshift  //压入到数组头部
shift  //弹出数组头部的一个元素
  1. 排序
a
> Array(3) [ "b", "c", "a" ]

a.sort()
> Array(3) [ "a", "b", "c" ]
  1. 元素反转
a.reverse()
> Array(3) [ "c", "b", "a" ]
  1. concat()
a.concat([1, 2, 3])
> Array(6) [ "c", "b", "a", 1, 2, 3 ]

a
> Array(3) [ "c", "b", "a" ]

注意:concat() 并没有修改数组,只是会返回一个新的数组

  1. 连接符join:打印拼接数组,使用特定的字符串连接
a.join('-')
> "c-b-a"
  1. 多维数组
arr = [[1, 2], [3, 4], ['5', '6']]
arr[1][1]
> 4

数组:存储数据(知道如何存、如何取,方法都可以自己实现)

3.3.3 对象

若干个键值对

var 对象名 = {
    属性名: 属性值,
    属性名: 属性值,
    属性名: 属性值
}

Js中是用 {…} 表示一个对象,键值对描述属性xxx: xxx,多个属性之间使用逗号隔开,最后一个属性不加逗号!

  1. 对象赋值
person.name = 'qinjiang'
> "qinjiang"
person.name
> "qinjiang"
  1. 使用一个不存在的对象属性,不会报错
person.haha
> undefined
  1. 动态的删减属性:delete
delete person.name
> true
person
> Object { age: 3, email: "24736743@qq.com", score: 0 }
  1. 动态的添加属性:直接添加
person.haha = "haha"
> "haha"
person
> Object { age: 3, email: "24736743@qq.com", score: 0, haha: "haha" }
  1. 判断属性值是否在这个对象中

JavaScript中的所有键都是字符串,值是任意对象

"age" in person
> true

//继承
"toString" in person
> true
  1. 判断一个属性是否是这个对象自身拥有的
person.hasOwnProperty("toString")
> false
person.hasOwnProperty("age")
> true

3.3.4 流程控制

  • if判断
let age = 3;
if (age > 3){
    alert("haha");
}else if(age < 3){
    alert("kuwa~");
}else {
    alert("kuwa~~");
}
  • while循环,避免程序死循环
while (age < 100){
    age = age + 1;
    console.log(age);
}

do{
    age = age + 1;
    console.log(age);
}while (age < 100)
  • for循环
for (let i = 0; i < 100; i++){
    console.log(i);
}
  • 数组循环
let age = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
//输出对象的值
age.forEach(
    function (value){
        console.log(value);
    }
)

//输出对象的key(下标)
for(let num in age){
    console.log(num);
    console.log(age[num]);
}

//遍历数组
for(let num of age){
    console.log(num);
}

3.3.5 Map和Set

ES6的新特性

  • Map
//ES6
//学生的成绩,学生的名字
//let names = ["tom", "jack", "haha"];
//let scores = [100, 90, 80];

let map = new Map([["tom", 100], ["jack", 90], ["haha", [80]]]);
let name = map.get("tom");  // 通过key获得value
console.log(name);

map.set("admin", 123456);  // 新增或修改
> Map(4) { tom → 100, jack → 90, haha  (1) [], admin → 123456 }

map.delete("tom");  // 删除
  • Set:无序不重复的集合
let set = new Set([3, 1, 1, 1, 1]);  // set可以去重
set.add(2);
set.delete(1);
console.log(set.has(3));  // 是否包含那个元素

3.3.6 iterator

遍历数组、map、set

let arr = [3, 4, 5];
for (let x of arr){
    console.log(x);
}

let map = new Map([["tom", 100], ["jack", 90], ["haha", 80]]);
for (let x of map){
    console.log(x);
}

let set = new Set([5, 6, 7]);
for (let x of set){
    console.log(x);
}

3.4 函数及面向对象

3.4.1 函数定义

  • 定义方式一

绝对值函数

function abs(x){
    if(x >= 0){
        return x;
    }else{
        return -x;
    }
}

一旦执行到return代表函数结束,返回结果!

如果没有执行return,函数执行完也会返回结果,结果就是 undefined 或 NaN

  • 定义方式二
var abs = function(x){
    if(x >= 0){
        return x;
    }else{
        return -x;
    }
}  // 类似java的匿名内部类

function(x){…} 这是一个匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数

  • 调用函数
abs(10)  // 10
abs(-10)  // -10

参数问题:javaScript可以传任意个参数,也可以不传参数

假设不存在参数,如何规避

//手动抛出异常来判断
if (typeof x !== 'number'){
    throw 'Not a Number';
}
  • arguments

arguments是一个JS免费赠送的关键字,代表传递进来的所有的参数,是一个列表

var abs = function(x){
    console.log("x => " + x);

    for (let i = 0; i < arguments.length; i++){
        console.log(arguments[i]);
    }
}

abs(1, 2, 3, 4)
x => 1 
1 
2
3 
4 

问题:arguments会包含所有的参数,我们有时候想使用多余的参数来进行附加操作,需要排除已有的参数

  • rest

获取除了已定义参数外的其他参数,rest参数只能卸载最后面,必须用…标识

function a(a, b, ...rest){
    console.log("a => " + a);
    console.log("b => " + b);
    console.log("rest => " + rest);
}

a(1, 2, 3, 4, 5, 6, 7, 8)
a => 1 
b => 2 
rest => 3,4,5,6,7,8

3.4.2 变量的作用域

  • 在Javascript,var定义变量实际是有作用域的,假设在函数体中声明,则在函数体外不可以使用(可以通过 闭包 实现)
'use strict'
function qj(){
    var x = 1;
    x = x + 1;
}
x = x + 2;  // Uncaught ReferenceError: x is not defined
  • 如果两个函数使用了相同的变量,只要在函数内部,就不冲突
'use strict'
function qj(){
    var x = 1;
    x = x + 1;
}

function qj2(){
    var x = 'A';
    x = x + 1;
}
  • 内部函数可以访问外部函数的成员,反之则不行
'use strict'
function qj(){
    var x = 1;

    function qj2(){
        var y = x + 1;
    }
    var z = y + 1;  // Uncaught ReferenceError: y is not defined
}
  • 假设内部函数变量和外部函数函数变量重名,采用就近原则
'use strict'
function qj(){
    var x = 1;

    //内部函数可以访问外部函数的成员,反之则不行
    function qj2(){
        var x = "A";
        console.log('inner: ' + x);  // inner: A
    }
    console.log('outer: ' + x);  // outer: 1
    qj2()
}
  • 提升变量的作用域
'use strict'
function qj(){
    var x = 'x' + y;
    console.log(x);
    var y = 1;
}

//上面的函数等价于下面的函数
function qj(){
    // var x, y, z...
    var y;
    var x = 'x' + y;
    console.log(x);
    y = 1;
}

> x undefined

JS执行引擎,自动提升了y的声明,但是不会提升变量y的赋值;这是在JavaScript建立之初就存在的特性,要养成规范:所有的变量定义都放在函数头部

function qj2(){
    var x = 1,
        y = x + 1,
        z, i, a; // underfined
    
    // 之后随意用
}
  • 全局函数
'use strict'
//全局变量
var x = 1;
function f(){
    console.log(x);
}
f()
console.log(x);

全局对象window

'use strict'
var x = 'xxx';
window.alert(x);  // alert()这个函数本身也是一个window变量
alert(window.x);  // 默认所有的全局变量,都会自动绑定在window对象上

JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量)假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域中都没有找到,就会报错 RefrenceError

var old = window.alert;
window.alert = function (){

};
//发现alert()失效了
window.alert(123);

//恢复
window.alert = old;
window.alert(456);
  • 规范

由于我们所有的全局变量都会绑定到我们的window上,如果不同的js文件使用了相同的全局变量,就会冲突 ~ 解决方法:

// 唯一的全局变量
var KuangApp = {};

// 定义全局变量
KuangApp.name = 'kuangshen';
KuangApp.add = function (a, b){
    return a + b;
}

把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题 jQuery

  • 局部作用域let

解决局部作用域冲突问题,建议都用 let 去定义局部作用域的变量

function a() {
    for (let i = 0; i < 100; i++){
        console.log(i);
    }
    console.log("i: " + (i + 1));  // Uncaught ReferenceError: i is not defined
}
  • 常量

在ES6之前,只有用全部大写字母命名的变量就是常量;建议不要修改这样的值

var PI = '3.14'
PI = '213'; //可以改变这个值

在ES6引入了常量关键字 const

const PI = '3.14'  // 只读变量
PI = '213'; // Uncaught TypeError: invalid assignment to const 'PI'

3.4.3 方法

  • 定义方法
var kuangshen = {
    name: 'qinjiang',
    birth: 2020,
    //方法:就是把函数放在对象的里面,对象只有两个东西(属性和方法)
    age: function (){
        let now = new Date().getFullYear();
        return now - this.birth;
    }
}

//属性
kuangshen.name
//方法,一定要带()
kuangshen.age()

拆开上面的代码

function getAge(){
    let now = new Date().getFullYear();
    return now - this.birth;
}

var kuangshen = {
    name: 'qinjiang',
    birth: 2020,
    age: getAge  //方法作为一个变量
}

//kuangshen.age()  // ok
//getAge()  //NaN, 现在属于window

this是无法指向,是默认指向调用它的那个对象

  • apply

在js中可以控制this指向

getAge().apply(kuangshen, []);  // this指向了kuangshen这个对象,参数为空
> 20

kuangshen.age()
> 20

getAge()
> NaN

213’; //可以改变这个值


在ES6引入了常量关键字 `const`

```javascript
const PI = '3.14'  // 只读变量
PI = '213'; // Uncaught TypeError: invalid assignment to const 'PI'

3.4.3 方法

  • 定义方法
var kuangshen = {
    name: 'qinjiang',
    birth: 2020,
    //方法:就是把函数放在对象的里面,对象只有两个东西(属性和方法)
    age: function (){
        let now = new Date().getFullYear();
        return now - this.birth;
    }
}

//属性
kuangshen.name
//方法,一定要带()
kuangshen.age()

拆开上面的代码

function getAge(){
    let now = new Date().getFullYear();
    return now - this.birth;
}

var kuangshen = {
    name: 'qinjiang',
    birth: 2020,
    age: getAge  //方法作为一个变量
}

//kuangshen.age()  // ok
//getAge()  //NaN, 现在属于window

this是无法指向,是默认指向调用它的那个对象

  • apply

在js中可以控制this指向

getAge().apply(kuangshen, []);  // this指向了kuangshen这个对象,参数为空
> 20

kuangshen.age()
> 20

getAge()
> NaN

PS:学习自狂神说java

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值