浏览器执行JS简介
浏览器分成两大部分 渲染引擎和JS 引擎
渲染引擎: 用来解析HTML与CSS,俗称内核,比如chrome浏览器的blink,老版本的webkit JS 引擎:也称为JS 解释器。用来读取网页中的JavaScript代码,对其处理后运行,比如chrome浏览器的v8
浏览器本身并不会执行JS代码,而是通过内置JavaScript引擎(解释器)来执行JS代码。JS引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以Javascript语言归为脚本语言,会逐行解释执行
概念
是一种运行在客户端(浏览器)的编程语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画等交互效果
组成
ECMAScript: ECMAScript 规定了JS的编程语法和基础核心知识,是所有浏览器厂商工共同遵守的一套JS语法工业标准
DOM---文档对象模型(Document Object Model)
文档对象模型,是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过DOM提供的接口可以对页面上的各种元素进行操作(大小,位置,颜色等)
BOM---浏览器对象模型(Browser Object Model)
BOM 是指浏览器对象模型,他提供了独立于内容的,可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框,控制浏览器跳转,获取分辨率等
上面的对象模型会在下一篇的WebAPI进行详细的介绍
书写位置
内部js
外部js
<body>
<script>
alert('努力 奋斗')
</script>
</body>
外部js
<body>
<!-- 内部样式 -->
<script>
alert('努力 奋斗')
</script>
<!-- 外部样式 -->
<script src="./1.js"></script>
<!-- script标签中间无需写代码,否则会被忽略! -->
</body>
script
标签中间无需写代码,否则会被忽略!
行内js
<button onclick="alert('你好,js')">点击我月薪过万</button>
js注释
单行注释
javascript 复制代码//这是单行注释
快捷键:ctrl+/
多行注释
javascript 复制代码/*这是多行注释,假装有很多的内容
假装有很多的内容假装有很多的内容
假装有很多的内容假装有很多的内容
假装有很多的内容假装有很多的内容 */
快捷键:shift + alt + a 块级注释
输入 、输出语句
输出语句
弹出框语句
语法: alert
javascript 复制代码alert('页面弹出内容')
控制台输出语句
语法:console.log
javascript 复制代码console.log('hello word!')
页面输出(给用户展示文本,可解析标签)
语法:document.write
javascript 复制代码document.write('页面输出内容')
输入语句
输入框语句
prompt
函数接收两个参数:
result = prompt('title', [default]);
浏览器会显示一个带有文本消息的模态窗口,还有 input 框和确定/取消按钮
js 复制代码title
显示给用户的文本
js 复制代码default
可选的第二个参数,指定 input 框的初始值(未输入值或值为空,初始值就会生效)
举个栗子:
javascript 复制代码let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`); // You are 100 years old!
IE 浏览器会提供默认值
第二个参数是可选的。但是如果我们不提供的话,Internet Explorer 会把 "undefined"
插入到 prompt。
我们可以在 Internet Explorer 中运行下面这行代码来看看效果:
javascript 复制代码let test = prompt("Test");
所以,为了 prompt 在 IE 中有好的效果,建议始终提供第二个参数:
javascript 复制代码let test = prompt("Test", ''); // <-- for IE
嫌麻烦的同学,可以直接忽略第二个参数,写成这样
javascript 复制代码prompt('页面输入内容')
语法:confirm
confirm('页面弹出的内容')
confirm
函数显示一个带有用户输入的内容以及确定和取消两个按钮的模态窗口。
点击确定返回 true
,点击取消返回 false
例如:
javascript 复制代码let isBoss = confirm("Are you the boss?");
alert( isBoss ); // 如果“确定”按钮被按下,则显示 true
这个语法和 prompt 语法不能说一模一样,只能说是非常的神似,不过使用体验上看上去有点鸡肋
上述所有方法共有两个限制:
1.模态窗口的确切位置由浏览器决定。通常在页面中心
2.窗口的确切外观也取决于浏览器。我们不能修改它
结束符
分号;
结束符可写可不写;(一行显示必须要加)
实际看团队要求,保证风格统一
数据类型
基本数据类型
检测数据类型
typeof
运算符返回参数的类型。当我们想要分别处理不同类型值的时候,或者想快速进行数据类型检验时,非常有用
对 typeof x
的调用会以字符串的形式返回数据类型:
typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (1)
typeof null // "object" (2)
typeof alert // "function" (3)
你可能还会遇到另一种语法:
typeof(x)
。它与typeof x
相同。简单点说:
typeof
是一个操作符,不是一个函数。这里的括号不是typeof
的一部分。它是数学运算分组的括号。通常,这样的括号里包含的是一个数学表达式,例如
(2 + 2)
,但这里它只包含一个参数(x)
。从语法上讲,它们允许在typeof
运算符和其参数之间不打空格,有些人喜欢这样的风格。有些人更喜欢用
typeof(x)
,尽管typeof x
语法更为常见。
数字型
number
(整数,小数,分数,负数)
作用:做数学运算
检测数据类型返回结果number
字符串型
string
由双引号" "
,单引号' '
,反引号‘ ’
包裹的字符串
作用:用来显示文字
检测数据类型返回结果string
boolean (布尔型)
真true
假false
作用:依据条件判断真假
检测数据类型返回结果boolean
未定义型
undefind
声明了变量但未赋值
检测数据类型返回结果undefind
空类型
null
已经赋值了,但是内容为空(毛坯房)
应用场景:如果一个变量里面确定存放的是对象,但是还未准备好对象,可以先放个null
注意点:特殊的值,表示有值但是值为空
null 检测数据类型返回结果object,这是一个Js
的bug,这个问题来自于 JavaScript 语言的早期阶段,并为了兼容性而保留了下来 null属于基本数据类型,但是Js
会归类为引用数据类型
引用数据类型
数组
对象
函数
变量
作用:在内存中开辟空间存储数据
本质:变量是程序中申请的一块用来存放数据的空间。
类似我们酒店的房间,酒店就是内存,酒店内的一个房间就可以看作是一个变量
一个现实生活的类比
如果将变量想象成一个“数据”的盒子,盒子上有一个唯一的标注盒子名字的贴纸。这样我们能更轻松地掌握“变量”的概念。
例如,变量 message
可以被想象成一个标有 "message"
的盒子,盒子里面的值为 "Hello!"
我们可以往盒子里放入任何值,
并且,这个盒子的值,我们想改变多少次,就可以改变多少次
变量的使用
1.创建变量
javascript 复制代码let userName
2.通过赋值运算符,给变量赋值
javascript 复制代码ueserName = 'Jack chen'
3.通过输出语法结合变量名进行查看
javascript 复制代码console.log('userName')//Jack chen
变量声明和赋值
声明
语法:let
+变量名
// 声明了一个年龄的变量
let age
// age=变量名
赋值
javascript 复制代码 // 声明了一个年龄的变量
let age //生成了一个空盒子
// age=变量名
// 给变量赋值为18
age = 18 //往盒子里装入一个内容为18的数字
// 控制台打印输出
console.log(age);
javascript 复制代码但是我们一般声明的同时直接赋值 (变量的初始化)
// 变量初始化
let age = 18
变量重复声明
会报错!
javascript 复制代码 // 声明了一个age变量,里面存放了一个18的数据
let age = 18
// 变量重复声明
let age = 20
// 控制台结果输出会报错
console.log(age);
在一行中同时声明多个变量
多个变量之间用逗号,
隔开
// 同时声明多个变量
let age = 18,uname = '张三'
看上去代码长度更短,但并不推荐这样,为了更好的可读性,请一行只声明一个变量
多行变量声明有点长,但更容易阅读:建议使用
javascript 复制代码let user = 'John';
let age = 25;
let message = 'Hello';
一些程序员采用下面的形式书写多个变量:
javascript 复制代码let user = 'John',
age = 25,
message = 'Hello';
……甚至使用“逗号在前”的形式:
javascript 复制代码let user = 'John'
, age = 25
, message = 'Hello';
技术上讲,这些变体都有一样的效果。所以,这是个个人品味和审美方面的问题。
我们还可以声明两个变量,然后将其中一个变量的数据赋值给另一个变量
javascript 复制代码let hello = 'Hello world!';
let message;
//把变量 Hello 里面的字符串'Hello word' 赋值给了 message
message = hello;
// 现在两个变量保存着相同的数据
alert(hello); // Hello world!
alert(message); // Hello world!
变量更新
步骤:
javascript 复制代码 // 声明了一个message变量,里面存放了一个hello的数据
let message = hello
// 变量里面的数据更新为word
message = word
console.log(message);//word
当变量的值发生了改变,之前的数据就被从变量中删除了
保留关键字
有一张 保留字列表,这张表中的保留字无法用作变量命名,因为它们被用于编程语言本身了。
比如,let
、class
、return
、function
都被保留了。
var与let区别!
1.var
可以先使用后声明,而let不用
2.var
可以重复声明而let不行
3.var
没有块级作用域,而let有,var会进行变量提升,而let不行
变量交换
交换操作(相当于就是重新赋值的过程)
需要一个新的临时变量名,来保存我们之前的变量
再声明一个新的变量
步骤:
1.声明一个新的临时空变量temp
2.把apple的 苹果汁 倒入 temp (赋值)
3.把orange橙子汁倒入 apple 杯子里面
4.把 temp里面的苹果汁倒入 orange杯子
javascript 复制代码 // 有一个装橙汁的容器,一个装苹果汁的容器
let orange = '橙子汁'
let apple = '苹果汁'
// 1.声明一个空临时变量
let temp
// 2.把apple赋值给空变量
temp = apple
// 3.把orange赋值给apple
apple = orange
// 4.temp的值给orange
orange = temp
变量的命名规范
规则:
不能用关键字
关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。即上面提到的保留关键字
只能用下划线、字母、数字、$组成,且数字不能开头
字母严格区分大小写,如 Age 和 age 是不同的变量
规范:
起名要有意义,见名知意(语义化)
遵守小驼峰命名法
第一个单词首字母小写,后面每个单词首字母大写。例:userName
正确命名变量
一个变量名应该有一个清晰、明显的含义,对其存储的数据进行描述。
变量命名是编程过程中最重要且最复杂的技能之一。快速地浏览变量的命名就知道代码是一个初学者还是有经验的开发者写的。
在一个实际项目中,大多数的时间都被用来修改和扩展现有的代码库,而不是从头开始写一些完全独立的代码。当一段时间后,我们做完其他事情,重新回到我们的代码,找到命名良好的信息要容易得多。换句话说,变量要有个好名字。
声明变量之前,多花点时间思考它的更好的命名。你会受益良多。
一些可以遵循的规则:
- 使用易读的命名,比如
userName
或者shoppingCart
。 - 离诸如
a
、b
、c
这种缩写和短名称远一点,除非你真的知道你在干什么。 - 变量名在能够准确描述变量的同时要足够简洁。不好的例子就是
data
和value
,这样的名称等于什么都没说。如果能够非常明显地从上下文知道数据和值所表达的含义,这样使用它们也是可以的。 - 脑海中的术语要和团队保持一致。如果网站的访客称为“用户”,则我们采用相关的变量命名,比如
currentUser
或者newUser
,而不要使用currentVisitor
或者一个newManInTown
。
常量
也是一个容器,用来保存数据,常量的值无法修改的
javascript 复制代码const age = 1
console.log(age)
常量值无法修改,强制修改会报错
常量必须要初始化(定义时必须要进行赋值)
常量和变量的使用场景:
1.当存储无需修改的数据时使用常量
2.当存储需要后期修改的数据时,应当使用
let
关键字来定义变量
大写形式的常数
一个普遍的做法是将常量用作别名,以便记住那些在执行之前就已知的难以记住的值。
使用大写字母和下划线来命名这些常量。
例如,让我们以所谓的“web”(十六进制)格式为颜色声明常量
javascript 复制代码const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// ……当我们需要选择一个颜色
let color = COLOR_ORANGE;
alert(color); // #FF7F00
好处:
COLOR_ORANGE
比"#FF7F00"
更容易记忆。- 比起
COLOR_ORANGE
而言,"#FF7F00"
更容易输错。 - 阅读代码时,
COLOR_ORANGE
比#FF7F00
更易懂。
什么时候该为常量使用大写命名,什么时候进行常规命名?让我们弄清楚一点。
作为一个“常数”,意味着值永远不变。但是有些常量在执行之前就已知了(比如红色的十六进制值),还有些在执行期间被“计算”出来,但初始赋值之后就不会改变。
例如:
javascript 复制代码const pageLoadTime = /* 网页加载所需的时间 */;
pageLoadTime
的值在页面加载之前是未知的,所以采用常规命名。但是它仍然是个常量,因为赋值之后不会改变。
换句话说,大写命名的常量仅用作“硬编码(hard-coded)”值的别名。
字面量
什么是字面量?
只要是能被js
识别的数据都被称之为字面量
javascript 复制代码字面量不是变量和常量,字面量指的是数据不是容器,所以字面量只能在赋值运算符=右边当数据使用
// 数字字面量
console.log(18)
// 字符串字面量
console.log('hello')
// 布尔字面量
console.log(true)
// 数组字面量
console.log([])
// 对象字面量
console.log({})
运算符
算术运算符:
加法: +
减法: -
乘法:*
除法:/
取余: %
求幂:**
算数运算符作用:进行数学运算
前四个都很简单,而 %
和 **
则需要说一说。
取余运算符是 %
,尽管它看起来很像百分数,但实际并无关联
a % b
的结果是 a
整除 b
的余数
alert( 5 % 2 ); // 1,5 除以 2 的余数
alert( 8 % 3 ); // 2,8 除以 3 的余数
除法取余运算符 %
应用场景
判断某个数字能否被整除
进行取余数运算时,前面一个数小于后面一个数,返回的余数则是第一个数
javascript 复制代码 // 控制台打印结果为5
console.log(5 % 10);
求幂
求幂运算 a ** b
将 a
提升至 a
的 b
次幂。
在数学运算中我们将其表示为
例如:
javascript 复制代码alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
就像在数学运算中一样,幂运算也适用于非整数。
例如,平方根是指数为 ½ 的幂运算:
javascript 复制代码alert( 4 ** (1/2) ); // 2(1/2 次方与平方根相同)
alert( 8 ** (1/3) ); // 2(1/3 次方与立方根相同)
除了常规的数字,还包括所谓的“特殊数值(“special numeric values”)”也属于这种类型:Infinity
、-Infinity
和 NaN
。
-
Infinity
代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值。我们可以通过除以 0 来得到它:
javascript 复制代码alert( 1 / 0 ); // Infinity
或者在代码中直接使用它:
javascript 复制代码alert( Infinity ); // Infinity
-
javascript 复制代码NaN
代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果,比如:alert( "not a number" / 2 ); // NaN,这样的除法是错误的
javascript 复制代码NaN
是粘性的。任何对NaN
的进一步数学运算都会返回NaN
:alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "not a number" / 2 - 1 ); // NaN
所以,如果在数学表达式中有一个
NaN
,会被传播到最终结果(只有一个例外:NaN ** 0
结果为1
)。
算术运算符优先级
先乘除取余,后加减,有小括号先算小括号里面的
javascript 复制代码 // 控制台打印结果为NaN
console.log('张三' * 5);
计算错误会出现
NaN
,不属于数字,但属于数字类型
拼接字符串
` ` 反引号包含数据
${ 变量名 }
+
数字相加,字符相连
// 页面弹出输入数据
let uname = prompt('请输入你的姓名')
let age = prompt('请输入你的练习时长')
// 页面输出打印展示
document.write(`大家好,我叫${uname},练习时长${age}年`)
${…}
内的表达式会被计算,计算结果会成为字符串的一部分。可以在 ${…}
内放置任何东西:诸如名为 name
的变量,或者诸如 1 + 2
的算数表达式,或者其他一些更复杂的。
需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入。
javascript 复制代码alert( "the result is ${1 + 2}" ); // the result is ${1 + 2}(使用双引号则不会计算 ${
赋值运算符
+=
-=
\*=
/=
%=
作用:是为了快速地进行赋值操作
javascript 复制代码let num = 10
num += 5 等价于 num = num + 5
注意点:赋值运算符,一定是把右边的值赋值给左边(变量或是常量)
链式赋值(Chaining assignments)
一个有趣的特性是链式赋值:
javascript 复制代码let a, b, c;
a = b = c = 2 + 2;
alert( a ); // 4
alert( b ); // 4
alert( c ); // 4
链式赋值从右到左进行计算。首先,对最右边的表达式 2 + 2
求值,然后将其赋给左边的变量:c
、b
和 a
。最后,所有的变量共享一个值。
同样,出于可读性,最好将这种代码分成几行:
javascript 复制代码c = 2 + 2;
b = c;
a = c;
这样可读性更强,尤其是在快速浏览代码的时候。
自增 / 自减运算符
作用:把变量每次加一或是减一
++自增
++在前,前缀式:++变量,先输出当前的值,+1在运算
--自减
javascript 复制代码 let num = 10
// 写法一
num = num + 1
// 写法二
num += 1
// 写法三
num ++
console.log(num);
// 最终所有结果都为11
自增/自减只能应用于变量。试一下,将其应用于数值(比如 5++
)则会报错
比较运算符
< | 大于 |
---|---|
小于 | |
<= | 小于等于 |
>= | 大于等于 |
== | 比较数值 |
=== | 比较值和类型 |
!== | 左右两边值和类型是否不全等(有一个不满足条件) |
!= | 左右两边是否不相等 |
作用:比较两个数据之间的关系
结果:返回布尔值true / false
===
比较的是值和类型
==
比较的是值
=
是赋值
运算符优先级
逻辑运算符
逻辑与 &&
逻辑或 ||
逻辑非 !
作用:在js
里需要同时判断多个条件使用
返回值:布尔类型
逻辑与 &&
查找规则:一假则假
逻辑与 ||
查找规则:一真则真
逻辑非 !
查找规则:取反(真变假,假变真)
案例
判断一个数是否能同时被4和100整除
javascript 复制代码 <script>
// 用户输入
let num = +prompt('请输入一个数进行计算:')
// 弹出计算结果
alert (num % 4 <mark>= 0 && num % 100 </mark>= 0)
</script>
空值合并运算符 '??'
空值合并运算符(nullish coalescing operator)的写法为两个问号 ??
。
由于它对待 null
和 undefined
的方式类似,所以在本文中我们将使用一个特殊的术语对其进行表示。为简洁起见,当一个值既不是 null
也不是 undefined
时,我们将其称为“已定义的(defined)”。
a ?? b
的结果是:
- 如果
a
是已定义的,则结果为a
, - 如果
a
不是已定义的,则结果为b
。
换句话说,如果第一个参数不是 null/undefined
,则 ??
返回第一个参数。否则,返回第二个参数。
空值合并运算符并不是什么全新的东西。它只是一种获得两者中的第一个“已定义的”值的不错的语法。
我们可以使用我们已知的运算符重写 result = a ?? b
,像这样:
result = (a !== null && a !== undefined) ? a : b;
??
的常见使用场景是提供默认值。
例如,在这里,如果 user
的值不为 null/undefined
则显示 user
,否则显示 匿名
:
let user; alert(user ?? "匿名"); // 匿名(user 未定义)
在下面这个例子中,我们将一个名字赋值给了 user
:
let user = "John"; alert(user ?? "匿名"); // John(user 已定义)
我们还可以使用 ??
序列从一系列的值中选择出第一个非 null/undefined
的值。
假设我们在变量 firstName
、lastName
或 nickName
中存储着一个用户的数据。如果用户决定不填写相应的值,则所有这些变量的值都可能是未定义的。
我们想使用这些变量之一显示用户名,如果这些变量的值都是 null/undefined
,则显示 “匿名”。
让我们使用 ??
运算符来实现这一需求:
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
// 显示第一个已定义的值
alert(firstName ?? lastName ?? nickName ?? "匿名");
与||
比较
或运算符 ||
可以以与 ??
运算符相同的方式使用
例如,在上面的代码中,我们可以用 ||
替换掉 ??
,也可以获得相同的结果:
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
// 显示第一个真值:
alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
纵观 JavaScript 发展史,或 ||
运算符先于 ??
出现。它自 JavaScript 诞生就存在了,因此开发者长期将其用于这种目的。
另一方面,空值合并运算符 ??
是最近才被添加到 JavaScript 中的,它的出现是因为人们对 ||
不太满意。
它们之间重要的区别是:
||
返回第一个 真 值??
返回第一个 已定义的 值
换句话说,||
无法区分 false
、0
、空字符串 ""
和 null/undefined
。它们都一样 —— 假值(falsy values)。如果其中任何一个是 ||
的第一个参数,那么我们将得到第二个参数作为结果。
不过在实际中,我们可能只想在变量的值为 null/undefined
时使用默认值。也就是说,当该值确实未知或未被设置时。
隐式转换
+
号两边有一个是字符串,就会把另外一个也转成字符串
+
-
*
/
等算术运算符都会把数据转成数字类型
+
号作为正号解析可以转换为数字类型
任何数据和字符串拼接都是字符串
显示转换
数字型
Number
(数字)
转成数字类型
若字符串内有非数字,会转换失败NaN
Parseint
(数字)
只保留整数,不会四舍五入
ParseFloat
浮点数(数字)
可以保留小数
数字类型转换
语法number
(其他数据类型)
- number只能转换纯数字的字符串,非纯数字字符串转换结果是NaN
- 布尔类型转数字,true为1,false为0
- null转数字类型是0
- undefind转数字类型是NaN
其他类型转数字类型为整数
语法:parselnt
(数据)
数据要以数字开头保留整数,非数字开头结果是NaN
其他类型转数字类型为小数
语法:parseFloat 浮点数(数据)
数据要以数字开头保留小数,非数字开头结果是NaN
字符串类型转换
其他类型转字符串
方式一
标签:入门,代码,javascript,基础,Js,复制,let,alert,函数 From: https://www.cnblogs.com/ministep/p/17483862.html