前端——JavaScript

何谓JavaScript?它与Java有什么关系?

JavaScript与HTML、CSS组合使用应用于前端开发,JavaScript是一门独立的语言,浏览器内置了JS的解释器。它除了和Java名字长得相似,没有半毛线关系。

JavaScript的存在形式

1.JavaScript代码的存在形式

  1. 代码写在JS文件中,在html文件头部引入<script type"text/javascript" src="JS文件"></script>
  2. 代码写在html文件头部的<scrpit></script>标签中

2.JavaScript代码存放位置

  • HTML的head中
  • HTML的body代码块底部(推荐)

由于Html代码是从上到下执行,如果Head中的js代码耗时严重,就会导致用户长时间无法看到页面,如果放置在body代码块底部,那么即使js代码耗时严重,也不会影响用户看到页面效果,只是js实现特效慢而已。

变量

JavaScript中变量的声明是一个非常容易出错的点,局部变量必须一个 var 开头,如果未使用var,则默认表示声明的是全局变量。

<script type="text/javascript">

    // 全局变量
    name = ‘seven‘;

    function func(){
        // 局部变量
        var age = 18;

        // 全局变量
        gender = "男"
    }
</script>

JavaScript中代码注释:

  • 单行 //
  • 多行 /*  */

注意:此注释仅在Script块中生效。

数据类型

JavaScript 中的数据类型分为原始类型和对象类型:

  • 原始类型

    • 数字
    • 字符串
    • 布尔值
  • 对象类型
    • 数组
    • “字典”
    • ...

特别的,数字、布尔值、null、undefined、字符串是不可变。

null是JavaScript语言的关键字,它表示一个特殊值,常用来描述“空值”。undefined是一个特殊值,表示变量未定义。

1.数字(Number)

JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示。

转换:

  • parseInt(..)    将某值转换成数字,不成功则NaN
  • parseFloat(..) 将某值转换成浮点数,不成功则NaN

特殊值:

  • NaN,非数字。可使用 isNaN(num) 来判断。
  • Infinity,无穷大。可使用 isFinite(num) 来判断。

2.字符串(String)

字符串是由字符组成的数组,但在JavaScript中字符串是不可变的:可以访问字符串任意位置的文本,但是JavaScript并未提供修改已知字符串内容的方法。

obj.length                           长度
obj.trim()                           移除空白
obj.trimLeft()
obj.trimRight)
obj.charAt(n)                        返回字符串中的第n个字符
obj.concat(value, ...)               拼接
obj.indexOf(substring,start)         子序列位置
obj.lastIndexOf(substring,start)     子序列位置
obj.substring(from, to)              根据索引获取子序列
obj.slice(start, end)                切片
obj.toLowerCase()                    大写
obj.toUpperCase()                    小写
obj.split(delimiter, limit)          分割
obj.search(regexp)                   从头开始匹配,返回匹配成功的第一个位置(g无效)
obj.match(regexp)                    全局搜索,如果正则中有g表示找到全部,否则只找到第一个。
obj.replace(regexp, replacement)     替换,正则中有g则替换所有,否则只替换第一个匹配项,

3.布尔类型(Boolean)

布尔类型仅包含真假,与Python不同的是其首字母小写。

  • ==      比较值相等
  • !=       不等于
  • ===   比较值和类型相等
  • !===  不等于
  • ||        或
  • &&      且

4.数组(列表)

JavaScript中的数组类似于Python中的列表

obj.length          数组的大小
obj.push(ele)       尾部追加元素
obj.pop()           尾部获取一个元素
obj.unshift(ele)    头部插入元素
obj.shift()         头部移除元素
obj.splice(start, deleteCount, value, ...)  插入、删除或替换数组的元素
obj.splice(n,0,val) 指定位置插入元素
obj.splice(n,1,val) 指定位置替换元素
obj.splice(n,1)     指定位置删除元素
obj.slice( )        切片
obj.reverse( )      反转
obj.join(sep)       将数组元素连接起来以构建一个字符串
obj.concat(val,..)  连接数组
obj.sort( )         对数组元素进行排序

其他

1.序列化

  • JSON.string(obj)      序列化:将对象转化为字符串
  • JSON.parss(str)       反序列化:将字符串转化为对象类型

2.转义

很多时候需要将数据转义后,保存在cookie中。

  • decodeURI( )                       URl中未转义的字符
  • decodeURIComponent( )    URI组件中的未转义字符
  • encodeURI( )                       URI中的转义字符
  • encodeURIComponent( )    转义URI组件中的字符
  • escape( )                              对字符串转义
  • unescape( )                          给转义字符串解码
  • URIError                               由URl的编码和解码方法抛出

3、eval()

JavaScript中的eval是Python中eval()和exec()的合集,既可以编译代码也可以获取返回值。

  • eval()
  • EvalError   执行字符串中的JavaScript代码

4、正则表达式

1、定义正则表达式

  • /.../  用于定义正则表达式
  • /.../g 表示全局匹配
  • /.../i 表示不区分大小写
  • /.../m 表示多行匹配

JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达式^和$,m模式也会使用^$来匹配换行的内容)

var pattern = /^Java\w*/gm;
var text = "JavaScript is more fun than \nJavaEE or JavaBeans!";
result = pattern.exec(text)
result = pattern.exec(text)
result = pattern.exec(text)

注:定义正则表达式也可以  reg= new RegExp()

2、匹配

JavaScript中支持正则表达式,其主要提供了两个功能:

  • test(string)     检查字符串中是否和正则匹配
n = ‘uui99sdf‘
reg = /\d+/
reg.test(n)  ---> true

# 只要正则在字符串中存在就匹配,如果想要开头和结尾匹配的话,就需要在正则前后加 ^和$
  • exec(string)    获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组。
获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组。

非全局模式
    获取匹配结果数组,注意:第一个元素是第一个匹配的结果,后面元素是正则子匹配(正则内容分组匹配)
    var pattern = /\bJava\w*\b/;
    var text = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)

    var pattern = /\b(Java)\w*\b/;
    var text = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)

全局模式
    需要反复调用exec方法,来一个一个获取结果,直到匹配获取结果为null表示获取完毕
    var pattern = /\bJava\w*\b/g;
    var text = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)

    var pattern = /\b(Java)\w*\b/g;
    var text = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)

3、字符串中相关方法

obj.search(regexp)                   获取索引位置,搜索整个字符串,返回匹配成功的第一个位置(g模式无效)
obj.match(regexp)                    获取匹配内容,搜索整个字符串,获取找到第一个匹配内容,如果正则是g模式找到全部
obj.replace(regexp, replacement)     替换匹配替换,正则中有g则替换所有,否则只替换第一个匹配项,
                                        $数字:匹配的第n个组内容;
                                          $&:当前匹配的内容;
                                          $`:位于匹配子串左侧的文本;
                                          $‘:位于匹配子串右侧的文本
                                          $$:直接量$符号

5、时间操作

JavaScript中提供了时间相关的操作,时间操作中分为两种时间:

  • 时间统一时间
  • 本地时间(东8区)

首先生成Date对象 var d = new Date();

get 系列:获取时间

set 系列:设置时间

设置分钟:

设置日期:

设置小时:

等等.....

6.定时器

1.setInterval("执行函数",间隔时间)  功能:每隔固定时间,执行指定函数,无限循环下去。(时间单位:毫秒)

        setInterval(function(){
            console.log();
        },5000),

2.(函数)(时间)  定时执行。在等待指定时间后,执行一次指定函数。(时间单位:秒)

        (function(arg){
            console.log(arg);
        })(1)

基本语法

1.条件语句

1. if...else... 语句

    if(条件){

    }else if(条件){

    }else{

    }

2. switch...case... 语句

    switch(name){
        case ‘1‘:
            age = 123;
            break;
        case ‘2‘:
            age = 456;
            break;
        default :
            age = 777;
    }

JS的if语句和switch语句和C语言的完全一样。

2.循环语句

JavaScript中支持若干种循环,其中最为常用的有三种循环

1.for循环(方式一)

var names = ["alex", "tony", "rain"];

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

2.for循环(方式二)

var names = ["alex", "tony", "rain"];

for(var index in names){
    console.log(index);
    console.log(names[index]);
}

3.while循环

while(条件){
    // break;
    // continue;
}

3.异常处理

try {
    //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
    // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
    //e是一个局部变量,用来指向Error对象或者其他抛出的对象
}
finally {
     //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。
}

函数

JavaScript中的函数分三类:普通函数、匿名函数、自执行函数。

1.普通函数

function func(){
     ......
}

2.匿名函数

匿名函数的存在形式多种多样

// 定义函数时并给函数取名,将匿名函数赋值给变量func
var func = function(arg){
     return "tony";
 }
//  定时器中的执行函数,可以以匿名函数形式存在
setInterval(function(){
    console.log();
},5000),

3.自执行函数

由两个括号组成,第一个括号内是执行函数,第二个括号内是等待执行的时间。

    (function(arg){
        console.log(arg);
    })(‘123‘)
// 123 秒后自动执行函数

作用域(重点)

作用域在许多程序设计语言中非常重要。通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。

1.以函数作为作用域

其他语言(如C,Java,C#):以代码块作为作用域(代码块即为大括号抱起来的部分)

public static void main ()
{
    if(1==1){
         String name = "seven";
    }
     System.out.println(name);
}
// 报错

Python中:以函数作为作用域

情况一:
def func():
    if 1==1:
        name = ‘alex‘
    print(name)

func()
 // 成功

情况二:
def func():
    if 1==1:
        name = ‘alex‘
print(name)

func()
print(name)
// 报错

JavaScript中:以函数作为作用域

var name=‘cc‘;
function func(){
    if(1==1){
        var name = ‘dd‘;
    }
    console.log(name);
}
func()

2.函数的作用域在被调用之前就已经创建

3.函数的作用域存在作用域链,也是在被调用之前创建

如果出现嵌套函数,则会出现作用域链;作用域在被执行之前就已经被创建,执行时只需要按照作用域链寻找即可。

同名变量的值,取决于离自己自己最近的作用域的值。(根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没找到抛出异常。)

示例1:

xo = ‘alex‘;

function Func(){
    var xo = "seven";
    function inner(){
        var xo = ‘alvin‘;
        console.log(xo);
    }
    inner();
}
Func();// 输出结果:alvin

示例2:

xo = ‘alex‘;

function Func(){
    var xo = "seven";
    function inner(){

        console.log(xo);
    }
    return inner;
}

var ret = Func();
ret();
// 输出结果: seven

示例三:

xo = ‘alex‘;

function Func(){
    var xo = "eirc";
    function inner(){

        console.log(xo);
    }
    xo = ‘seven‘;
    return inner;
}

var ret = Func();
ret();
// 输出结果: seven

上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。

示例四:

xo = ‘alex‘;
function Bar(){
    console.log(xo);
}

function Func(){
    var xo = "seven";

    return Bar;
}

var ret = Func();
ret();
// 输出结果: alex

上述代码,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> Bar函数作用域
  • 全局作用域 -> Func函数作用域

当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。

4.函数内局部变量提前声明

编译阶段生成作用域链,同时找到所有局部变量,执行var声明操作,但并没有赋值。

在JavaScript中如果不创建变量,直接去使用,则报错:

console.log(xxoo);
// 报错:Uncaught ReferenceError: xxoo is not defined

JavaScript中如果创建值而不赋值,则该值为 undefined,如:

var xxoo;
console.log(xxoo);
// 输出:undefined

在函数内如果这么写:

function Foo(){
    console.log(xo);
    var xo = ‘seven‘;
}
 // 解释过程中: var xo;
Foo();
// 输出:undefined

上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined

JavaScript面向对象

定义类和实例化示例:

function Foo(n){
        this.name = n;
        this.sayName = function(){
            console.log(this.name);
        }
}

var obj = new Foo("we");
  • Foo是类名
  • this代指对象,相当于Python中的self
  • 创建对象需要用new关键字,区别于函数调用

以上代码可以发现,从外壳来看,类与函数长得很像,它与函数的形式区别在于:1.this的使用2.实例化时的new关键字

在Python中,类实例化若干个对象后,每个对象内存中包含变量,但不包含方法,方法在类中,我们认为这是合理的。然而JavaScript不一样,每个对象中都存在相同的方法,这样浪费内存,不合理。

解决办法是:将方法写在prototype原型中

Foo的原型:
        Foo.prototype = {
            "sayName":function(){
                console.log(this.name);
            }
        }

当创建对象并调用方法时,如果在类中没有找到就会去原型中去寻找。将所有方法写在原型中,就达到了节省内存的目的。

JavaScript词法分析

JS代码执行前有一个类似编译的过程即词法分析(AO分析:active object),词法分析主要有三个步骤:

  1. 分析形式参数;
  2. 分析局部变量;
  3. 分析函数声明表达式;

在这里你可能会有问题:已经明白了作用域为什么还要看词法分析呢?词法分析和作用域在JS代码执行过程中各分担什么作用?带着这些疑问先往下看:

分析过程:

1.首先分析形式参数,赋给AO对象

  先看函数的形式参数,添加到AO的属性,并且这个时候值为undefined

  再看接收的实参,如果有,负载之前的undefined

2.局部变量

  检查局部变量,如果遇到不同名变量,添加属性并赋值为undefined

  如果有遇到同名变量,不做任何修改

3.函数声明表达式(优先级最高)

  遇到函数,添加属性,并把函数赋值给这个属性。

  如果该函数和前面的变量同名,则将变量覆盖,因为函数的优先级更高。

先来看示例一

function t1(age) {
    console.log(age);
    var age = 27;
    console.log(age);
    function age() {}
    console.log(age);
}

t1(3);

首先词法分析:

  1.生成AO对象

  2.分析形参,AO.age = undefined;

    发现实参,赋值AO.age = 3;

  3.分析局部变量发现同名变量age,不做任何修改

  4.分析函数age,因为优先级高,所以覆盖,即AO.age = function age(){}

整个过程只有一个变量名,所以词法分析的结果是:AO.age = function age(){}

执行阶段:

  1.第一行输出age,即词法分析的结果function age(){};

  2.遇到 var age = 27 ,给age赋值为27;

  3.输出age为27

  4.输出age为27

执行完毕,感觉懵逼?多此一举? 要记住,词法分析和执行是两个不同的阶段,词法分析在前,执行在后

继续看示例二

function t1(age) {
        var age;
        console.log(age);
        var age = 23;
        console.log(age);
        function age() {}
        console.log(age);
    }

t1(22)    // 与示例一代码不同之处:在第一次输出之前定义了同名变量,但没有赋值

词法分析阶段:

  1.生成AO对象

  2.分析形参,AO.age = undefined;

   分析实参,赋值,AO.age = 22;

  3.分析局部变量age,与前面同名,不做任何修改

  4.分析局部变量age,虽然赋值23,但因为同名,不做任何修改

  5.分析函数age,覆盖AO.age = function age(){}

分析结果:AO.age = function age(){}

执行阶段:

  1.第一次输出时,没有做赋值,所以输出词法分析结果function age(){}

  2.var age = 23;值被修改

  3.第二次输出:23

  4.第三次输出:23

示例三

function t1(age) {
        var age;
        console.log(age);
        function age() {}
        console.log(age);
        var age = 23;
        console.log(age);
    }

t1(22)  // 与实例二代码区别:将函数位置提前

词法分析阶段:

  1.生成AO对象

  2.分析形参,AO.age = undefined;

   分析实参,AO.age = 22;

  3.分析函数age,覆盖:AO.age = function age(){};

  4.分析局部变量age,虽然被赋值,但在词法分析阶段函数优先级高,故age属性仍然为上一步的值

分析结果:AO.age = function age(){}

执行阶段:

  1.第一次输出,为词法分析结果  function age(){}

  2.第二次输出,为词法分析结果  function age(){}

  3.age被重新赋值,age = 23

  4.第三次输出,为23

示例四:

function t1(age) {
    var age;
    console.log(age);
    age = 23;
    console.log(age);
    function age() {
        console.log(age);
    }
    age();
    console.log(age)
}

t1(22)

词法分析阶段:

  1.生成AO对象

  2.分析形式参数AO.age = undefined;

   分析实参AO.age = 23;

  3.分析局部变量var age,不做改变

  4.分析局部变量var age = 23,不做改变

  5.分析函数,AO.age = function age(){console.log(age)}

分析结果:AO.age = function age(){console.log(age)}

执行阶段:

  1.第一次输出:function age(){console.log(age)}

  2.age被重新赋值,age=23

  3.第二次输出:23

  4.执行 "age()" 代码,但是此时age是普通变量而非函数,因此语法错误,会报错

JavaScript的词法分析介绍到这里,现在对词法分析和作用域的作用做一下梳理:

  • 作用域      是程序执行过程所遵守的规则
  • 词法分析  可以理解为程序执行前的初始化,在程序执行的最开始提供变量的初值

原文地址:https://www.cnblogs.com/V587Chinese/p/9457831.html

时间: 2024-10-09 14:39:45

前端——JavaScript的相关文章

nodejs 和web前端JavaScript什么区别

web前端javascript组成: ECMAScript,(是js的标准,js是它的具体实现和扩展,它描述语言的语法和基本对象,如:语法,运算符,语句,继承机制,数据结构以及一些内置对象) DOM(文档对象模型),描述处理网页内容的方法和接口,将整个文档document解析成dom树供用户使用js对文档进行处理. BOM(浏览器对象模型),描述可以和浏览器窗口交互的方法和接口(对象结构),如:window对象,history.location.navigator等. nodejs除了语言基础E

基于七牛API开发的前端JavaScript SDK

这是我们工程实践的内容,由于时间原因,具体不赘述,啊~主要还是因为懒o(╯□╰)o工程实践的题目为openedx后端管理系统的功能拓展与优化,我们要优化的一个主要功能便是实现视频本地化上传,我们采用的视频云服务商为七牛云存储,以下链接是基于它的API开发的前端JavaScript SDK,http://developer.qiniu.com/docs/v6/sdk/javascript-sdk.html我的任务是看完,找到需要改的参数,刚刚大概看了一下,很多东西不是很明白,先把我觉得需要改的参数

前端javascript模板

doT.js——前端javascript模板引擎问题备忘录 我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的了这么丑陋.拙劣的代码呢,也许是他们的忍受力极强,压根就没想去寻找解决方法. 可是,我,是万难不能接受这种丑陋的解决方式的.有没有优雅的解决方法呢,于是在网上搜索到了doT.js. 主页很简洁,就一个页面,研究了一下,就顺利的上手了,相当的简单易用.主要分两步走. 1.写模板 写模板,就用官方文档里

菜鸟学前端--javascript基础

在学习过css相关的知识,有了前端工程师的一些基础知识.但要较好的掌握前端,必须要学习好javascript的知识. 下面将从基本语法.变量.关键字.保留字.语句.函数.BOM等角度阐释. 一.基本语法 javacript作为一种面向对象的.脚本级的轻量语言,与java一脉相承. 命名:区分大小写,弱类型定义(一般采用var,不限制类型). 行末分号可有可无(从经验上来看,推荐写,可以提高代码阅读质量). 括号用于代码段. 注释与C.java类型,单行用"//",段注释用"/

JAVA后台与前端JAVASCRIPT之间AES加密解密互通

调试了一天终于把java后台与javascript之间的AES加密解密成功了,记录一下过程. 后台java解密代码:解码算法及模式为 AES/CBC/PKCS5Padding key与iv要为16位 得到16的字符数组按照16进制编码转化为字符串 public static String encrypt(String content, String key) throws Exception { try { Key keySpec = new SecretKeySpec(key.getBytes

在C#后端处理一些结果然传给前端Javascript或是jQuery

在C#后端处理一些结果然传给前端Javascript或是jQuery,以前Insus.NET有做过一个例子<把CS值传给JS使用 >http://www.cnblogs.com/insus/archive/2011/05/04/2036271.html 是使用Literal控件来实现. 不过还是有些复杂. 本次Insus.NET再简化一些,把值传给前端的jQuery. 用户请求一个网页,送至服务器之后,然后传给客户端.因此服务端传值给jQuery或是javascript是件很容易的事.反之的话

前端JavaScript面试技巧

第1章 课程简介从几个常见面试开始,讨论针对一个题目的分析思路,总结题目对应的知识点.最后列出所有 JS 知识点的集合 -- JS 知识体系框架.1-1 课程简介(导学)1-2 前言1-3 几个面试题1-4 如何搞定所有面试题 第2章 JS基础知识(上)讲解 JS 基础语法相关的面试题,分析原理以及解答方法.这一章节讲解了基础知识的第一部分:变量的类型和计算.以及JS "三座大山" -- 原型.作用域和异步中的第一座大山:原型.2-1 变量类型和计算-12-2 变量类型和计算-22-3

小猿圈之2019年前端JavaScript面试题(二)

小猿圈前端讲师今天继续给你总结js面试题,前面一篇文章咱们已经有一片js基础部分面试题,今天小猿圈web讲师为你讲解js前端应用设计问题,一定要好好看哦,为了能赢在其他人前面. JavaScript前端应用设计问题 1.解释单向数据流和双向数据绑定. Angular1.x基于双向数据绑定,而React,Vue,Elm等基于单向数据流架构. 2.单向数据流架构在哪些方面适合MVC? MVC拥有大约50年的悠久历史,并已演变为MVP,MVVM和MV*.两者之间的相互关系是什么?如果MVC是架构模式,

Fundebug前端JavaScript插件更新至1.8.2,修复2个小BUG

摘要: 修复2个BUG,请大家及时更新. Fundebug前端异常监控服务 Fundebug是专业的程序异常监控平台,我们JavaScript插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括: JavaScript执行错误 资源加载错误 HTTP请求错误 unhandledrejection WebSockect连接错误 并且,我们可以记录用户行为."录制"用户操作视频,帮助开发者快速复现BUG,提高Debug效率. Fundebug前端异常监控插件更新至1.

八大前端JavaScript趋势和工具

JavaScript的世界正在快速发展. 前端开发(和网络开发)的世界正在以极快的速度发展.如今,如果不借助前端或Webpack.React Hooks.Jest.Vue和NG元素,你会很快被远远抛下.不过,情况正在发生改变. 尽管开发人员和技术人员在前端领域中的数量逐年上升,生态系统却有标准化的趋势.新技术和工具的出现正在改变当下的规则. 总体趋势肯定会是一种基于组件构成的用户界面标准化,会影响从样式到测试甚至状态管理的所有方面,并且总体具有更好的模块度.这将包括围绕web组件.ES模块.组件