admin 管理员组文章数量: 1087649
Java Script基础语法
目录
- 引言
- 一、JavaScript 的书写形式
- 1.1行内式
- 1.2 内嵌式
- 1.3 外部式
- 二、输入输出
- 2.1 输入: prompt
- 2.2 输出: alert
- 2.3 输出: console.log
- 三、语法概览
- 3.1 变量的使用
- 3.2 基本数据类型
- 四、运算符
- 4.1相等运算符
- 4.2 逻辑运算符
- 五、数组
- 5.1 创建数组
- 5.2 获取数组元素
- 5.3 获取数组长度
- 5.4 使用 push 进行追加元素
- 5.5 删除数组中的元素.
- 六、函数
- 6.1 语法格式
- 6.2 函数表达式
- 6.3 关于参数个数
- 6.4 作用域
- 七、对象
- 7.1 使用 字面量 创建对象 [常用]
- 7.2 使用 new Object 创建对象
- 7.3 使用构造函数创建对象
- JavaScript 的对象和 Java 的对象的区别
引言
JavaScript
(简称 JS)
- 是世界上最流行的编程语言之一;
- 是一个脚本语言, 通过解释器运行;
- 主要在客户端(浏览器)上运行, 现在也可以基于
node.js
在服务器端运行;
Node.js
这是一个js
的运行平台.(对标的是浏览器)浏览器是运行在客户的.Node.js
既可以运行在客户端,也可以运行在服务器上(单独的执行程序).就可以给js
赋予客户端开发/服务器开发的能力.
JavaScript 的能做的事情:
- 网页开发(更复杂的特效和用户交互)
- 网页游戏开发
- 服务器开发(node.js)
- 桌面程序开发(Electron, VSCode 就是这么来的)
- 手机 app 开发
JavaScript 之父 布兰登 * 艾奇 (Brendan Eich)
JavaScript 和 HTML 和 CSS 之间的关系:
- HTML: 网页的结构(骨)
- CSS: 网页的表现(皮)
- JavaScript: 网页的行为(魂)
JavaScript 运行过程:
- 编写的代码是保存在文件中的, 也就是存储在硬盘(外存上).
- 双击
.html
文件浏览器(应用程序)就会读取文件, 把文件内容加载到内存中(数据流向:硬盘 => 内存
) - 浏览器会解析用户编写的代码, 把代码翻译成二进制的, 能让计算机识别的指令(解释器的工作)
- 得到的二进制指令会被 CPU 加载并执行(数据流向:
内存 => CPU
)
浏览器分成渲染引擎 + JS 引擎.
渲染引擎: 解析html + CSS
, 俗称 “内核”;
JS 引擎: 也就是JS 解释器
. 典型的就是Chrome
中内置的V8
;
JS 引擎逐行读取 JS 代码内容, 然后解析成二进制指令, 再执行
JavaScript 的组成:
ECMAScript
(简称 ES): JavaScript 语法;
DOM
: 页面文档对象模型, 对页面中的元素进行操作;浏览器提供的一组,操作页面元素的API;
BOM
: 浏览器对象模型, 对浏览器窗口进行操作;浏览器提供的一组,操作浏览器窗口的API;
但是要想完成更复杂的任务, 完成和浏览器以及页面的交互, 那么就需要 DOM API 和 BOM API
.这主要指在浏览器端运行的 JS. 如果是运行在服务端的 JS , 则需要使用 node.js 的 API,就不太需要关注 DOM 和 BOM.
一、JavaScript 的书写形式
JavaScript
代码可以嵌入到 HTML
的 script
标签中.
1.1行内式
直接嵌入到 html 元素内部:
<input type="button" value="点我一下" οnclick="alert('haha')">
注意, JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示.
HTML 中推荐使用双引号, JS 中推荐使用单引号
1.2 内嵌式
写到 script 标签中:
<script>alert("haha");
</script>
1.3 外部式
写到单独的 .js
文件中:
然后到另一个文件中对其进行引用:
<script src="app.js">
关于注释:
- JS的注释
//
- HTML的注释:
<!-- -->
- CSS的注释:
/* */
二、输入输出
2.1 输入: prompt
弹出一个输入框:
prompt("请输入名字:");
2.2 输出: alert
弹出一个警示对话框, 输出结果:
alert("hello");
2.3 输出: console.log
在控制台打印一个日志(供程序员看):
// 向控制台输出日志
console.log("这是一条日志");
三、语法概览
3.1 变量的使用
定义一个变量:
var变量名=初始值;
// 创建变量let num = 10;//创建一个名为num的,数字类型的变量var s = 'hello';//创建了一个名字为s的,字符串类型的变量.var arr = [];//创建了一个名字为arr的,数组类型的变量.
现在更倾向于使用let
来代替var
.var
是旧版本(早期的设计),有很多地方其实是违背直觉.
使用变量:读取+修改:
在变量的修改的时候,有个小问题:如果本来num是一个数字类型,在赋值的时候可以给它赋一个数字类型,也可以赋一个字符串类型,也可以赋任意类型,这个时候num变量的类型,也就随之发生改变了。
num = 20;//变量的类型可以在运行的过程中随着赋值的改变而发生改变---‘动态类型’num = 'hello';console.log(num)
变量的类型可以在运行的过程中随着赋值的改变而发生改变,称为“动态类型”。(Python,PHP,Ruby…)
像Java这样的语言,不支持这种运行时类型发生改变.这种行为,称为"静态类型"。(C,C++,Java,Go,Rust…)
3.2 基本数据类型
JS 中内置的几种类型:
number
: 数字. 不区分整数和小数.
var a = 07; // 八进制整数, 以 0 开头
var b = 0xa; // 十六进制整数, 以 0x 开头
var c = 0b10; // 二进制整数, 以 0b 开头
一个八进制数字对应三个二进制数字,一个十六进制数字对应四个二进制数字. (两个十六进制数字就是一个字节).
特殊的数字值:
Infinity
: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.-Infinity
: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.NaN
: 表示当前的结果不是一个数字.
var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);
//和Java类似,如果把字符串和数字相加,那么就会得到一个“字符串拼接”的效果.
console.log('hehe' - 10);//hehe10
可以使用 isNaN
函数判定是不是一个非数字:
console.log(isNaN(10)); // false
console.log(isNaN('hehe' - 10)); // true
boolean
: true 真, false 假.
Boolean 参与运算时当做 1
和 0
来看待:
console.log(true + 1);//2
console.log(false + 1)//1
这样的操作其实是不科学的. 实际开发中不应该这么写.
string
: 字符串类型.
如果字符串里本身就包含了引号,这个时候就可以通过单双引号灵活搭配的形式,来避免使用转义字符:
let s1 = "my name is 'zhang'";console.log(s1);let s2 = 'my "name" is zhang ';console.log(s2);let s3 = "My name is \"zhangsan\"";console.log(s3);
有些字符不方便直接输入, 于是要通过一些特殊方式来表示:
\n
\\
\'
\"
\t
求长度:求长度通过length
属性
let s = '哈哈';console.log(s.length);//2
此处这里的长度,单位是“字符"。
字符串拼接(和Java类似)直接使用+
来进行拼接。
数字和字符串拼接得到字符串;数字和数字拼接得到的是数字。
//字符串拼接let a = 'hello';let b = 20;console.log(a+b);//hello20
undefined
: 只有唯一的值 undefined. 表示未定义的值.
如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型:
let c;console.log(c);//undefined
undefined 和字符串进行相加, 结果进行字符串拼接:
let a;
console.log(a + "10"); // undefined10
undefined 和数字进行相加, 结果为 NaN:
let a;
console.log(a + "10); // NaN
null
: 只有唯一的值 null. 表示空值.
let d = null;console.log(d);//nullconsole.log(d + 10); // 10console.log(d + "10"); // null10
null 和 undefined 都表示取值非法的情况, 但是侧重点不同.
null 表示当前的值为空. (相当于有一个空的盒子)
undefined 表示当前的变量未定义. (相当于连盒子都没有)
如果一个编程语言,越支持隐式类型转换,认为类型越弱.(C,JS,PHP认为是弱类型的编程语言);
如果一个编程语言,越不支持隐式类型转换,认为类型越强.(Java, Go, Python认为是强类型的编程语言);
强类型,意味着类型之间的差异更大,界限是更明确的;
弱类型,意味着类型之间的差异不大,界限是更模糊的;
静态类型/动态类型vs强类型/弱类型是不相关的概念(正交)
C++是兼容C的.(意味着C的隐式类型转换,对于C++也是同样支持的)
四、运算符
JavaScript 中的运算符和 Java 用法基本相同. 此处不做详细介绍。
这里介绍下比较运算符里面的相等运算符:
4.1相等运算符
JS中比较相等,有两种风格:
-
==
比较相等(会进行隐式类型转换)
!=
只是比较两个变量的值,而不比较两个变量的类型.如果两个变量能够**通过隐式类型转换,转成相同的值,**此时就认为这两个变量是相等的。 -
===
比较相等(不会进行隐式类型转换)
!==
既要比较变量的值,也要比较类型.如果类型不相同,就直接认为不相等.
let e = 10;let f = '10';console.log(e == f);//trueconsole.log(e === f);//false
谈到比较两个对象,有三个维度的比较:
1.比较身份.(是不是同一个对象)
2.比较值.(对象里存储的数据是否相同)
3.比较类型.(两个对象是否是同一个类型)
Java中 ==
比较身份.equals
可以被重写.不重写默认也是比较身份.通过重写来设定成比较值.instanceof
比较类型.
JS: ==
只是比较值.,===
同时比较值和类型.
4.2 逻辑运算符
&&、||
这俩个运算符和Java 中的&&和||
差别挺大的。
Java中的&&和||
行为非常简单.就是返回一个true
或者false
,JS
中的&&和||
返回的是其中的一个表达式。
c = a || b:
如果a的值,为真(非0),此时c的值,就是表达式a的值.
如果a的值,为假(为0),此时c的值,就是表达式b的值.
c = a && b也是类似:
如果a的值为假, 此时c的值,就是表达式a的值.
如果a的值为真, 此时c的值,就是表达式b的值.
这属于一种短路求值:如果a这边已经能确定表达式的值了,就不必计算b了。
let x = null;if(!x){x= 0;}// 等价于x = x || 0;
JS中,不区分整数和小数,都是number.
console.log(1/2);//0.5
五、数组
5.1 创建数组
- 使用 new 关键字创建
let arr = new Array();
这种写法,更像是, Java 中创建了一个对象(很少使用)
- 使用字面量方式创建 [常用]
let arr1 = [];let arr2 = [1,2,3,4];let arr3 = [1,'hello',undefined,true];//数组中保存的内容称为 "元素"console.log(arr1);console.log(arr2);console.log(arr3);
JS 的数组不要求元素是相同类型.
5.2 获取数组元素
使用下标的方式访问数组元素(从 0 开始):
let arr3 = [1,'hello',undefined,true];//获取数组中的元素console.log(arr3[0]);console.log(arr3[1]);console.log(arr3[2]);console.log(arr3[3]);
如果下标超出范围读取元素, 则结果为 undefined
:
let arr3 = [1,'hello',undefined,true];console.log(arr3[8]);//undefined
当给超出数组下标的元素赋值时,长度变成了101,然后数组的内容,前四个元素不变,下标为100的元素是10.但是中间的空属性*96
意思就是中间这些元素仍然是undefined
。
let arr3 = [1,'hello',undefined,true];arr3[100] = 10;console.log(arr3);
如果给数组下标为-1的元素赋值:
//-1是一个属性,并没有影响到数组的长度arr3[-1] = 10;console.log(arr3);
JS 中的数组,不是一个正经数组!除了能接数组的活,还能接map
的活(表示键值对)=>这里说数组是一个map,更准确的说是一个“对象”.
在JS里,是可以在运行时给对象新增属性的.
下面的arr['hello']
就是在给arr
这个对象新增了一个属性.属性的名字是hello
,属性的值是10
.
arr.hello = 10;arr['hello'] = 10;console.log(arr);//[hello: 10]console.log(arr['hello']);//10console.log(arr.hello);//10
这些语法都不是JS独有的.动态类型的语言都是这样设定的。(PHP的设定方式几乎和JS一模一样,但是 Python 略有差别,本质不变)
5.3 获取数组长度
通过.length
就能获取到。JS 里,length属性是可以改的。
let arr2 = [1,2,3,4];console.log(arr2.length);
5.4 使用 push 进行追加元素
最常见的插入操作, push
方法能够给数组末尾追加一个元素.(Java ArrayList
里面的add操作)。
代码示例: 给定一个数组, 把数组中的奇数放到一个 newArr
中:
var arr = [9, 5, 2, 7, 3, 6, 8];
var newArr = [];
for (var i = 0; i < arr.length; i++) {if (arr[i] % 2 != 0) {newArr.push(arr[i]);}
}console.log(newArr);
let arr4 = [];for(let i = 0;i < 10;i++){arr4.push(i);}console.log(arr4);
5.5 删除数组中的元素.
splice
这个方法,针对数组中的某个区间进行替换.既可以用于删除,也可以用于插入元素.
//删除元素arr4.splice(3,2);//从下标为3的位置开始,删除两个元素console.log(arr4);
六、函数
函数(function)和方法(method)是同一个东西,不同的马甲。
通常情况下,不去考量这两个概念的区别.但是如果非要考量,可以这样理解:
函数是和“对象"独立开来的代码片段.
方法是依托于对象的代码片段. 方法=>成员函数
在Java中,由于本身这样的代码片段都是依托于类和对象的.因此Java中就都是“方法"。
6.1 语法格式
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {函数体return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
这里的形参列表,不必写参数类型,返回值类型也不需要写。
函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次.
function f() {console.log("hello");
}
f();//hello
调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)
6.2 函数表达式
另外一种函数的定义方式。
// function hello() {// console.log("hello");// }//hello是一个函数名.hello后面没有(),//说明这个操作,不是函数调用而只是一个单纯的函数的赋值.//f1是function类型的变量// let f1= hello;//通过f也能够调用到上面的 hello 函数//f1();//hello//上面可以合并为,也可以省略hello//匿名函数--》lambda表达式let f1= function () {console.log("hello");};console.log(typeof (f1));//functionf1();//hello
此时形如 function() { }
这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示.后面就可以通过这个 f1
变量来调用函数了.
6.3 关于参数个数
实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配.
- 如果实参个数比形参个数多, 则多出的参数不参与函数运算;
- 如果实参个数比形参个数少, 则此时多出来的形参值为
undefined
;
//最多可以支持7个参数相加
function add(a,b,c,d,e,f,g) {//第一种写法// if(a == undefined){// a = 0;// }//另外一种写法//如果不对下面的值进行处理,则返回的结果是NaNa = 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));//30console.log(add(10,20,30));//60
传入的实参类型是可以任意的.只要能够支持函数内部的逻辑(比如此处要求两个参数能进行相加即可):
function add(x,y){return x + y;}let result = add(1,2);console.log(result);result = add("hello","world");console.log(result);result = add(10,"hello");console.log(result);
正因为有这样的特性,JS天然就是不需要"泛型"/"重载"这样的语法的.
6.4 作用域
作用域:某个标识符名字在代码中的有效范围.
ES6
其实是JS
的版本.JS原名ECMAScript,也可以简称为ES. JS的版本都是用ES数字来表示的.JS中的最新版本也是到ES十几,ES6的地位就相当于Java8在java 中的地位.
在 ES6
标准之前, 作用域主要分成两个:
全局作用域: 在整个 script
标签中, 或者单独的 js
文件中生效.
局部作用域/函数作用域: 在函数内部生效.
在ES6
之后,引入了let
,也就有了块级作用域.一个变量在{}
内部定义,是无法被{}
外部访问的。在JS
里面,{}
内部的代码,是可以访问到{}
外部的变量的。
作用域链:内部函数可以访问外部函数的变量. 采取的是链式查找的方式. 从内到外依次进行查找。
let num = 10;function f3() {function f2() {console.log(num);}f2();}f3();
JS中的作用域,是支持"逐级向上"查找的.当前是在f2这个函数里尝试打印num.但是在f2中,没有num变量,于是就往上级找,找到了f3这里,但是在f3里,也没num.
于是继续往上找,找到了全局作用域.找到了num(如果最后的全局作用域也没找到,就会报错).
如果在作用域链的不同节点上,存在多个同名的变量咋办?
从里往外找,先找到谁就算谁
七、对象
对象就是一些属性和方法的集合.在 JS 中, 字符串, 数值, 数组, 函数都是对象.
在Java中,对象需要先有类,然后针对类的实例化才产生对象.Java中,类可以视为是一种自定义的类型.(Cat类和Dog类两个不同的类型).
在JS 中,对象是不依托于类的,在JS中所有的对象都是一个类型. object
在JS中,直接通过{}
的方式,就可以创建对象.
7.1 使用 字面量 创建对象 [常用]
使用 { }
创建对象
//对象let student={name: '张',age:20,height:180,weight: 120,sing:function () {console.log("ni");},jump:function () {console.log("舞蹈");}};console.log(student.name);//zhangconsole.log(student.age);//20student.sing();//ni
每个属性和方法,其实都是通过"键值对"这样的方式来表达的.{}
表示这是个对象.
键值对之间使用,
来分割,键和值之间使用:
来分割.后续就可以根据student.属性名
方式来进行访问了.对象的定义(和Java有一定区别)
7.2 使用 new Object 创建对象
var student = new Object(); // 和创建数组类似student.name = "蔡徐坤";student.height = 175;student['weight'] = 170;student.sayHello = function () {console.log("hello");
}console.log(student.name);console.log(student['weight']);student.sayHello();
JS中一个对象中有哪些成员,也都是动态可以改变的,注意, 使用 { }
创建的对象也可以随时使用 student.name = "蔡徐坤";
这样的方式来新增属性.
7.3 使用构造函数创建对象
前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便的创建多个对象.
基本语法:
function 构造函数名(形参) {this.属性 = 值;this.方法 = function...
}
var obj = new 构造函数名(实参);
- 当看到函数内部,通过
this.
这样的方式来创建属性的时候,此时这个函数大概率就是构造函数了. - 构造函数的函数名首字母一般是大写的.
- 构造函数的函数名可以是名词.
- 构造函数不需要 return.
- 创建对象的时候必须使用 new 关键字.
不使用构造函数创建对象:
var mimi = {name: "咪咪",type: "中华田园喵",miao: function () {console.log("喵");}
};
var xiaohei = {name: "小黑",type: "波斯喵",miao: function () {console.log("猫呜");}
}
var ciqiu = {name: "刺球",type: "金渐层",miao: function () {console.log("咕噜噜");}
}
使用构造函数重新创建Cat对象:
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();
实际上JS在穿件对象的时候,以第一种写法为主。
JavaScript 的对象和 Java 的对象的区别
- JavaScript 没有 “类” 的概念
JS没有class这个概念,适用于ES6之前.ES6之后,也引入了class 关键字,可以让定义对象,就更接近于Java 了这种方式,仍然没有上述第一种方法简单.
因此,在JS中也是有一些现成的对象的,像数组,本质上也可以视为是一个对象。 - JS里没有封装,继承,多态这样的一些面向对象的典型特性
JS中没有原生提供继承这种机制的.但是JS里有一个曲线救国的方法,“原型”,基于原型机制,可以模拟实现一个类似于继承的效果.(把一个对象的所有属性,给自动的加入到一个新的对象中) - JavaScript 对象不区分 “属性” 和 “方法”
JavaScript 中的函数是 “一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行。 - JavaScript 对象没有 private / public 等访问控制机制.
对象中的属性都可以被外界随意访问.
本文标签: Java Script基础语法
版权声明:本文标题:Java Script基础语法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1700300756a386765.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论