js基础知识

一、基础扫盲

1、JavaScript特点

a)解释型

没有编译的概念,代码是由浏览器里的解释器解释运行的。

代码执行到报错停止,但是前面执行的代码,效果依然会体现。

浏览器不同或解释器不同,代码执行效果可能会不一样。(系统引擎和V8引擎)

b)弱类型

类型检查弱,并且当解释器期望在什么位置需要什么类型时,会根据一定的规则完成自动转换。比如,在if语句中期望提供布尔型,如果你提供的不是布尔型,则自动转换而不给任何提示。

c) Unicode字符集

变量名支持中文

\u0053\u0074\u0072\u0069\u006e\u0067.\u0066\u0072\u006f\u006d\u0043\u0068\u0061\u0072\u0043\u006f\u0064\u0065就代表String.fromCharCode

d)代码从上往下执行,哪个写在前面就哪个先执行。不像别的语言有一个入口。

e)JS的标准 ECMAscript ES5

3、编程语言共性

  1. 注释
  2. 关键字
  3. 标识符
  4. 常量
  5. 变量
  6. 运算符
  7. 语句
  8. 函数
  9. 数组

区分大小写

忽略换行和多余空格(分号;代表语句结束)

写代码的时候注意全角和半角,一般符号都只认识半角

4、注释

// 单行注释

/* ...*/多行注释

5、关键字

6、保留字

在当前标准下,还没有特殊含义,但是可能后续标准会用到,也轮不到我们用。

7、标识符

说白了就是一些变量名,函数名等。使用之前必须自己预先定义

字母、数字、下划线、美元符号(数字不允许为首)中文

驼峰命名法

8、直接量(常量)

直接出现在代码中,执行过程中不变的量。

二、数据类型

  1. 原始类型       字符串、数值、布尔值

null、undefined

  1. 对象类型       对象、数组、函数等

  1. null和undefined

一般情况下,null代表空,undefined代表未定义。

  1. 数值

JavaScript不区分整数和小数

var a = 0;

var a = 1.3;

  1. 字符串

单引号和双引号意义完全一样

var a = “小肩膀”;

var a = ‘小肩膀’;

字符串中有引号的时候

var a = “小’肩膀”;

var a = ‘小”肩膀’;

d)布尔值 true false

JS在适当的时候会自动完成类型转换。也就是如果当它需要布尔型的时候,对它来讲,就只有两种值,真值和假值

false undefuned null 0 -0 NaN "" //空字符串

以上7种为假值,其余均为真值

三、变量

1、变量的概念

变量其实就是内存中的一块存储区域,声明定义了一个变量就是在内存开辟了一块空间,用来存储数据。

变量名实际就对应这块空间的地址

2、变量声明的基本格式

var a;             //定义一个变量

var a,b;           //定义两个变量,中间用逗号运算符分隔

var a = 0;         //定义的同时初始化   这个等价于 var a; a = 0;

var a = 0, b = 1;

变量用var关键字重复声明不会报错,但是会覆盖前面的同名变量。不单单要注意变量与变量的重名,还要注意变量与函数,函数与函数的重名。

没有以var关键字定义的变量,在任何位置都是全局变量,不建议故意不写var去定义一个全局变量。

3、变量声明提前

    alert(a);

    var a;         //弹出undefined 

    alert(a);

    var a = 5;     //弹出undefined  只是声明提前 赋值不提前

4.变量作用域

不包含在任何函数内部的代码叫顶层代码,定义在顶层代码中的变量就是全局变量。定义在函数中的变量,就是局部变量。

    function test(){

        var a = 5;

    }

    test();

    alert(a);      //报错 a是test函数里面的局部变量 外面不能直接访问

    function abc(){

        var b = 6;

        function test(){

            alert(b);

        }

        test();

    };

abc();

alert(b);      //先弹出6 然后报错

四、运算符

1、算数运算符

a)+ -

当+-作为一元运算符时,代表强制转换到数字,如果无法转换,返回NaN。比如:+[]  +{}  +new Date()

当加号作为二元运算符时,加号也可以表示字符串连接,只要加号有一边是字符串,则优先字符串连接。

b)* / %

c)++ --

++ 递增 比如:i++ 就等同于i = i + 1的简写

2、位运算符

&   位与

|   位或

^   位异或

~   位非(位取反)

<<  左移

>>  右移

>>> 无符号右移

3、赋值运算符

=       //在任何位置都代表赋值

+=      //i += 2; 等价于i = i + 2;

-=  *=  /=  %=

4、关系运算符

a)==   !=

等号在任何位置都代表比较,两边会自动类型转换

b)===  !==

等号在任何位置都代表比较,两边不会自动类型转换

5、比较运算符

<   >   <=  >=

6、逻辑运算符

&& 与  || 或  ! 非(取反)

a) &&的特点

短路:从左往右,碰到假就不执行后面的表达式(相当于if的简写)

        var a = 0;

        (a == 1) && (a = 3);

        alert(a);

应用于赋值

var b = 1;

var a = “张三”+ b && c;

b) ||的特点

短路:从左往右,碰到真就不执行后面的表达式

var a = 0;

a || (a = 100);

alert(a);

应用于赋值

var a = 100;

a = a || 0;

alert(a);

7、逗号运算符

同时定义两个或两个以上变量。

多个表达式语句连接成一条语句。

8、三元运算符(相当于if...else的简写)

表达式1 ? 表达式2 : 表达式3

var b = 1,c = 1;

var a = b == c? 3 : 6;

console.log(a);

9、typeof 运算符

用来判断数据类型

10、instanceof

一般用来判断对象属于哪个类

五、语句

JS中以分号代表一个语句的结束,如果多个表达式语句之间用的逗号运算符分隔,算一条语句。

1、代码执行的三种结构

顺序结构

分支结构

循环结构

2、分支结构

  1. if
  2. switch

跟别的语言有所不同,表达式的结果类型可以是string、number、boolean、对象、array。与if最大的区别就是switch没法做区域判断

        3. 跳转语句break continue

break可以用在switch和循环中

continue只能用在循环中

2、循环结构

  1. while
  2. do...while
  3. for 一般用于数组遍历

for(初始化表达式;循环条件表达式;循环后的操作表达式)

              {

                     执行语句;

              }

可以放任意表达式,多个表达式之间用逗号分隔

  1. for...in   一般用于对象和数组遍历

4、省略括号的情况

实际上if、whlie、do...while、for、for...in语句后面都只能跟一条一句。如果需要多个语句。你要么用花括号括起来,代表这些是复合语句。或者用逗号运算符连接成一条语句。

5、块级作用域

在JS中用var定义的变量没有块级作用域。在流程控制语句中定义的变量,作用域范围也是整个函数。【只看函数的{}】

let定义的变量有块级作用域【for{ }】

6、throw语句

if(x < 0)  throw new Error(“x不能为负数”);

7、异常处理语句 try/catch/finally

try{

//...

}catch(e){

//try语句中报错 这里的代码才会执行

//...

}finally{

//不管try语句是否异常 这里代码都会执行

//...

}

8、“use strict”指令    //严格模式

六、数组

1、数组的概念

数组也是一个容器,它是一堆数据的集合,是连续的一块内存地址空间。

2、数组的声明

var arr = [];             //定义空数组

var arr = new Array();       //定义空数组

var arr = new Array(5);      //定义一个5个成员的数组

3、length属性用于获取数组长度

4、数组下标从0开始

5、JS的数组没有越界的概念,会返回undefined

6、JS的数组非常灵活,数组成员可以是任意类型的组合

var a = 50;

var arr = [

        “abc”,

        59,

        [100,200],

        {x:300,y:400},

        function(){return 500;},

        function(){return 600;}(),

        10 + a

];

7、数组成员(元素)的读写(访问和赋值)

8、作为数组的字符串 字符串切片

var str = "javascript";

console.log(str[5]);        //charAt

9、数组遍历(for和for...in,和for...of)

for...in和for...of(ES6):前者接受数组下标,后者接受数值的值

arr.map(function(value,index){

})

(ES5)

arr.map(function(value,index){

        //可以在函数内部this调用obj

},obj)

foreach和map用法类似

var arr = [

  [1,2,3],

  [4,5],

  [7]

],c = 0;

for(var i=0;i<arr.length;i++){

  for(var k=0;k<arr[i].length;k++){

    c += arr[i][k];

  }

}

console.log(c);

七、对象

1、对象的分类

a) 内置对象

包括数组、日期、正则表达式等,这些有对应的内部类。提供了很多方法供我们使用。

b) 宿主对象

主要指DOM对象,由浏览器实现。不同的浏览器,可能不一样。

无需创建,可以直接使用。

c) 自定义对象

2、对象的属性(方法)

a) 自有属性

b) 继承属性

3、对象的创建

var obj={};          //隐式创建

var obj=new Object();

4、对象的结构

{属性名1:属性值,属性名2:属性值}

5、对象属性的定义和访问

a) var obj = { x : 1, y : 2 };        //初始化的时候就定义属性   

b) obj.x       //这里必须写死在代码中

c) obj[“x”] //这里是一个字符串 可以拼接 动态生成

d) 对象的属性可以随时创建,并且前面不能加var关键字

6、对象方法的定义和调用

obj.test = function(a,b){

alert(100);

};

obj.test(1,2);

7、序列化对象(JSON)

JSON.stringify()      //对象转字符串

JSON.parse()          //字符串解析成对象

9、对象属性遍历(for...in)

for(var name in obj){

        obj[name];

}

10、window对象和navigator对象

a) 全局对象概念

当JS以浏览器为运行环境的时候,window是它的全局对象,可以用this引用。

当JS以调试器为运行环境的时候,也有全局对象,但不叫window,也可以用this引用。

b) 全局对象的特点

顶层代码中定义的所有变量,都是全局对象的属性

顶层代码中定义的所有函数,都是全局对象的方法

全局对象调用它的属性和方法时,可以省略对象名称

var a = 5;

alert(window.a);

function test(){

alert(666);

}

window.test();

c) navigator 对象

navigator 是window下的一个属性,也是一个对象,该对象包含有关浏览器的信息。

JSON数据解析

1、JSON.解析() JSON.成员数() JSON.取通用属性()       JSON.清除()

2、JSON数组最外层一定是花括号,表示是对象。

3、数组表现形式

最外层用中括号表示,多个数组成员之间用逗号隔开。数组下标从0开始。数组成员访问方式,数组名[数组下标]

4、对象表现形式

最外层用花括号表示,多个属性之间用逗号隔开,每个属性都是 属性名:属性值 的名值对。属性访问方式,对象名.属性名 或者 对象名[“属性名”]

JSON解析数组

JSON解析对象

JSON访问特殊属性名

八、函数

1、函数的概念

函数是JS的一个基本组成单位,每个函数用来完成一定的功能,函数里可以调用别的函数来完成功能。函数是JS里最小的封装。

2、函数声明、定义/实现、调用的概念

a) 函数的结构

          function 函数名(参数列表){

      //语句

      //return 语句

   }

b) 函数的声明

//第一种

function test(){

var a = 5;

alert(a);

}

test();

//第二种

var test = function(){

var a = 5;

alert(a);

}

3、函数声明的提前

第一张方式声明会自动提前

test();

function test(){

alert(5);

}

第二种方式定义的函数 声明无法提前,会报错

4、JS函数中可以再定义函数(私有函数)

5、函数的形参和实参

function test(a,b){

return a+b;

}

test(5,6);

6、return语句

a) return只能用在函数体中

b) return后面跟多个表达式,用逗号分隔,只返回最后一个表达式计算的结果

function test(){

  var a,b,c;

  return a = 100,b = 200,c = a + b;

}

test();

c) 在return和后面的表达式之间不能有换行,JS会自动补全分号

return

true;  会解析成return;true;

7、匿名函数【没有名字】

function(){

        //.....

}

作用:1、赋值给变量、赋值给对象的属性

  2、作为参数传入函数,类似回调函数

  3、作为命名空间,定义完后直接调用(防止和其他参数冲突!)

8、匿名函数的调用

(function(){

//....

})();

(function(){

//....

}());

!function(){

//....

}();

9、匿名函数的传参

    !function(a,b){

        alert(a + b);

    }(5,6);

10、作为命名空间的函数

(function(){

//...

})()

11、函数的作用域

        (function(){

            function test(){

                var a = 5;

                alert(a);

            }      

        })();

        test();            //报错 test是私有函数 外面不能直接访问

12、如何在外部间接调用私有属性和函数?(!!!!!)

第一种:

        var obj = function(){

            var b = 6;

            function test(){

                var a = 5;

                alert(a);

            }

            return {

                b : b,

                test : test

            }

        }();

//这里有括号是把函数的返回值赋给obj 不加括号是把函数赋给obj;

        obj.test();

        alert(obj.b);     //弹出5 再弹出6

第二种:

        var obj = {};//自己创建个属性,再把匿名函数的fun挂到里面

        !function(o){

var b = 6;

            function test(){

                var a = 5;

                alert(a);

            }

o.b = b;

            o.test = test;

        }(obj);

        obj.test();

alert(obj.b);     //弹出5 再弹出6

//把obj去掉会报错 test() 跟obj.test() 不是同一个东西

第三种:

        !function(w){

            function i(){

                var a = 5;

                alert(a);

            }

            w.Hex = i;

        }(window);

        Hex();

//弹出5 正常调用应该是window.Hex  window对象在浏览器里可以省略

//在浏览器里Hex() 和 window.Hex() 是同一个东西

JS调试器里没有window这个对象 所以会报未定义

即使定义为空对象,它也没有可以省略的功能,所以一般定义成this,把调试器的全局对象的引用,赋值给window。这样window调用属性和方法的时候就可以省略了。

13、那么怎么在调试器里改装呢?

第一种方法 补全

    var window = {};

    function test(){

        return Hex.x;    //return window.Hex.x;

    }

    !function(w){

//...

            w.Hex = {x:2};

    }(window);

对上面的代码来个稍微的变形

    var window = {};

    function test(){

        return Hex.x;    //return window.Hex.x;

    }

    !function(){

//...

            window.Hex = {x:2};

    }();

第二种方法 去掉对象改装成全局变量

    var window = {};

var Hex = {};         //定义成一个全局变量

    function test(){

        return Hex.x;

    }

    !function(w){

            Hex = {x:2};  //这里window去掉

    }(window);

14、函数的重载

JS中没有函数的重载 无法根据函数参数的不同 来分辨不同的函数

一定要注意函数与函数,函数与变量,变量与变量不要重名

    function test(a){

        return a;

    }

    function test(a,b){

        return a + b;

    }

    alert(test(5));

    //NaN (not a Number)

15、作为值的函数

把函数当做参数

function test(a,b){

return a+b;

}

function abc(a,b,f){

return f(a,b);

}

abc(5,6,test);

16、JS支持可变参数arguments

17、this关键字

在顶层代码引用this就代表window

函数里的this 谁调用它 就指代谁

18、函数的方法    call apply

九、闭包

1、作用

让函数内的局部变量,可以达到保留的效果

2、形成条件

函数返回的是一个函数

​​​​​​​

3、通常写法

十、类

1、构造函数、原型对象和实例化的概念

//构造函数   constructor

function People(){

  this.name = "小肩膀";

  this.age = 28;

}

//方法只定义了一次 可以减少内存的使用

//People.prototype 构造函数的原生对象

People.prototype.eat = function(){

  return "饭";

}

//实例化对象

var people1 = new People();  //new后面的构造函数名 要和定义的时候对应

var people2 = new People();

console.log(people1.eat == people2.eat);

2、原型链

  1. 当我们定义一个对象 var obj = {}; 等价于var obj = new Object();

   所以它的原型是Object.prototype

b) 当我定义一个数组 var arr = []; 等价于var arr = new Array();

   所以它的原型是Array.prototype

   Array.prototype的原型是Object.prototype

c) 当我们实例化一个对象var people = new People();

   它的原型是People.prototype

   People.prototype的原型是Object.prototype

d) 每一级都会继承

十一、JS的内部类

1、JS事先定义好的一些类,方便使用。内部类的父类是Object

2、分为动态类和静态类

   动态类使用的时候,先创建一个对象实例,然后使用其属性和方法

   静态类通过类名,调用属性和方法    Math.random()

Math类

Math是静态类,提供了常用的数学函数和常数,我这给大家介绍几个最常用的函数,其它的请大家参考javascript帮助文档。

abs(x)        返回数的绝对值

ceil(x)     对一个数进行上舍入

floor(x)    对一个数进行下舍入

max(x,y)   求x,y中较大的数

min(x,y)   求x,y中较小的数

round(x)   对 x进行四舍五入

random()   一个大于0小于1的16位小数位的数字(含0但是不含1)  

Date类

Date()        返回当前日期和时间

getDate()    从Date对象返回一个月中的某一天

getDay()     从Date对象返回一周中的某一天

getMonth()     从Date对象返回月份

getYear()  从Date对象返回年

getHours()     从Date对象返回小时数

getMinutes() 从Date对象返回分钟

getSeconds() 从Date对象返回秒数  

toLocaleString()

取现行时间戳

Date.now();

new Date().getTime();

new window.Date().getTime();

String类

indexOf()         返回某个字符串值在该字符串中首次出现的位置

substr()      提取取从start下标开始的指定数目的字符

substring()   提取字符串中介于两个指定下标之间的子串

charAt()       返回指定位置的字符

length         属性,可以得到字符串的长度

toString()     将对象中的数据转成某个格式的字符串

split()      把字符串分割为字符串数组

match()/replace()/search() 

toUpperCase()字符串到大写

toLowerCase()字符串到小写

Array类

Array提供了对数组的操作,使用Array对象可以轻松的创建数组,

并对数组进行删除、排序和合并等操作。

concat()     连接两个或更多的数组,并返回结果。

sort()         对数组的元素进行排序

toString()   把数组转换为字符串,并返回结果

pop()         删除并返回数组的最后一个元素

push()             向数组的末尾添加一个或更多元素,并返回新的长度

splice()     方法用于插入、删除或替换数组的元素

length         属性,获取长度

全局函数

parseInt

parseFloat

  1. 事件

click  鼠标点击

submit 表单提交

事件

按钮点击的四种写法

在HTML中直接绑定

在JS中,获取DOM对象,添加onclick属性

添加事件监听,addEventListener() 或 attachEvent()

jQuery方法on绑定

十二、jQuery

//jquery获取元素的值

$("#user").val();

$("#user").val(a);

$(".user").val(a);

$("input[type='password']").val();

//jquery遍历数组

var b = ["张三","李四","王五"];

$.each(b,function(i,v){

    alert(i + " " + v);

})

var arr = [1,2,3,4,5,6,7,8,9,10],c = 0;

$(arr).each(function(i,v){

    c = c + v;

});

alert(c);

//原生js遍历数组

for(var i = 0; i < b.length; i++){

    alert(i + " " + b[i]);

}

$().click(function(){})

$().on(‘click’,function(){})

十三、ajax

$.get("login.php");

var data = "u=15968079470&p=2222222222";

data = {

    u : "15968079470",

    p : "2222222222",

};

$.post("login.php",data,function(response){

        //....

})

$.ajax({

    url : "",

    type : "",

    data : {

   

}

    success : function(response){

        //....

    }

})

十四、模块化编程

define()

  1. 用来定义一个模块
  2. 这是一个函数
  3. 一般接收三个参数

   a) 是一个字符串,指定文件存在路径,或者说是模块名

   b) 是一个数组,指定依赖,本模块正常执行,必须要用到的一些文件

   c) 是一个函数,该函数的参数,分别对应第二个参数的数组成员调用后        的接口。函数体内部是本模块的具体代码。一般该函数会有一个返回值,        返回本模块调用的接口

4、我们的处理方式是掐头去尾留中间。如果一个实战中涉及多个模块,则        用闭包封装,闭包最后返回的为该模块的接口

5、这个函数原生JS不具备。也就是说是利用原生JS封装出来的一个函数。        所以这个函数,网站也有可能会自己去实现,而不是调用别人的写好的        JS库。也就是你可能会看到名字不是define,但是写法很像的代码。我        们的处理方式类似

十五、JS混淆

1、eval加密

如果代码是服务器返回的,通常我们不能直接文本取中间,我们要用JSON解析。

因为代码是以文本的方式发送的,所以有可能字符会冲突,服务器发送过来会用转义字 符转义 “\” 。用JSON解析就去自动处理掉这些东西。

2、把变量名、函数名、参数名等,替换成没有语义,看着又很像的名字。

_0x21dd83、_0x21dd84、_0x21dd85

3、用十六进制文本去表示一个字符串  \x56\x49\x12\x23

4、利用JS能识别的编码来做混淆

\u6210\u529f表示中文字符(成功)。JS是Unicode编码,本身就能识别这种编码。类似的一些变量名,函数名都可以用这个表示,并且调用。

\u0053\u0074\u0072\u0069\u006e\u0067.\u0066\u0072\u006f\u006d\u0043\u0068\u0061\u0072\u0043\u006f\u0064\u0065就代表String.fromCharCode

('')['\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72']['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'];效果等同于String.fromCharCode

5、把一大堆方法名、字符串等存到数组中,这个数组可以是上千个成员。然后调用的时候,取数组成员去用(arr[1001])。

var arr = ["Date","getTime"];

var time = new window[arr[0]]()[arr[1]]();

console.log(time);

6、charCodeAt、String.fromCharCode结合eval就是一种混淆手段

这个名字好认,所以也有的网站会自己写一个类似的函数,用这个函数转换,并把函数名改掉。

var a = "你好";a.charCodeAt(0);         //把字符转换成ASCII码

String.fromCharCode(20320,97,49,65);   //把ASCII码转换成字符

有时候服务器会直接发送一段ASCII过来(65,56,48,97),然后用

String.fromCharCode转换后,再用eval执行

  1. 字符串加密后发送到前端,然后前端调用对应的函数去解密,得到明文

   对于这种,

首先把函数括号中的所有参数匹配出来,包括里面的逗号

然后调用JS解密得到明文字符串

最后用明文字符串加上引号,替换函数名(参数列表)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值