前端面试题|JS前端面试题(一)


文章目录

  • 1.简述同步和异步的区别
  • 2.怎么添加、移除、复制、创建、和查找节点
  • 3.实现一个函数clone 可以对Javascript中的五种主要数据类型(Number、string、Object、Array、Boolean)进行复制
  • 4.如何消除一个数组里面重复的元素
  • 5.写一个返回闭包的函数
  • 6.使用递归完成1到100的累加
  • 7.Javascript有哪几种数据类型
    • 基本数据类型:
    • 复合数据类型:
    • 特殊数据类型:
  • 8.如何判断数据类型
    • 判断js中的数据类型的几种方法
      • 1、最常见的判断方法:typeof
      • 2、判断已知对象类型的方法: instanceof
      • 3、根据对象的constructor判断: constructor
      • 4、通用但很繁琐的方法: prototype
      • 5、万能的方法:jquery.type()
  • 9.console.log(1+'2')和console.log(1-'2')的打印结果
  • 10.Js的事件委托是什么,原理是什么
  • 11.如何改变函数内部的this指针的指向
    • 1.bind:
    • 2.call:
    • 3.apply
    • 四.总结
  • 12.列举几种解决跨域问题的方式,且说明原理
    • 1.jsonp
    • 2、使用window.name来进行跨域
    • 3、使用HTML5中新引进的window.postMessage方法来跨域传送数据
  • 13.谈谈垃圾回收机制的方式及内存管理
    • **一、垃圾回收机制—GC**
    • **二、内存管理**
  • 14.写一个function ,清除字符串前后的空格
  • 15.js实现继承的方法有哪些
    • JS继承的实现方式
      • 1、原型链继承
      • 2、构造继承
      • 3、实例继承
      • 4、拷贝继承
      • 5、组合继承
      • 6、寄生组合继承
  • 16.判断一个变量是否是数组,有哪些办法
  • 17.let ,const ,var 有什么区别
  • 18.箭头函数与普通函数有什么区别
  • 19.随机取1-10之间的整数
  • 20.new操作符具体干了什么
  • 21.Ajax原理
  • 22.模块化开发怎么做
  • 23.异步加载Js的方式有哪些
  • 24.xml和 json的区别
  • 25.webpack如何实现打包的
  • 26.常见web安全及防护原理
  • 27.用过哪些设计模式
  • 28.为什么要同源限制
  • 29.offsetWidth/offsetHeight,clientWidth/clientHeight与scrollWidth/scrollHeight的区别
  • 30.javascript有哪些方法定义对象

1.简述同步和异步的区别
  • 同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
  • 异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容
2.怎么添加、移除、复制、创建、和查找节点 (1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
【前端面试题|JS前端面试题(一)】createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
3.实现一个函数clone 可以对Javascript中的五种主要数据类型(Number、string、Object、Array、Boolean)进行复制
Object.prototype.clone=function(){ var o= this.constructor===Array? [] : {}; for(var e in this){ o[e]= typeof this[e]==="object" ? this[e].clone() : this[e]; } return o; };

4.如何消除一个数组里面重复的元素
function qc(arr1){ let arr = []; for( let i = 0; i < arr1.length; i++) { if( arr.indexOf(arr1[i]) == -1) { arr.push(arr1[i]) } } return arr; } arr1 = ["1","1","3","5","2","24","4","4","a","a","b"]; console.log(qc(arr1));

5.写一个返回闭包的函数 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。闭包就是能够读取其他函数内部变量的函数。可以把闭包简单理解成”定义在一个函数内部的函数”。
闭包有三个特性:
1.函数嵌套函数;
2.函数内部可以引用外部的参数和变量;
3.参数和变量不会被垃圾回收机制回收。
闭包就是一个函数的返回值为另外一个函数,在outer外部可以通过这个返回的函数访问outer内的局部变量.
function outer(){ var val = 0; return function (){ val += 1; document.write(val + "
"); }; } var outObj = outer(); outObj(); //1,执行val += 1后,val还在 outObj(); //2 outObj = null; //val 被回收 var outObj1 = outer(); outObj1(); //1 outObj1(); //2

闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗(如果上例中定义很多outer(),则内存中会保存很多val变量)。
javascript的垃圾回收原理:
(1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
(2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
那么使用闭包有什么好处呢?使用闭包的好处是:
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在
6.使用递归完成1到100的累加
function sum(num) { if( num==1 ){ return 1; } return num+sum(num-1); } console.log(sum(100))

7.Javascript有哪几种数据类型 基本数据类型: 字符串 String
数字 Number
布尔 Boolean
复合数据类型: 数组 Array
对象 Object
特殊数据类型: Null 空对象
Undefined 未定义
8.如何判断数据类型 判断js中的数据类型的几种方法 判断js中的数据类型有一下几种方法:typeof、instanceof、 constructor、 prototype、 $.type()/jquery.type(),
接下来主要比较一下这几种方法的异同。
判断js中的数据类型的几种方法
1、最常见的判断方法:typeof
alert(typeof a)------------> string alert(typeof b)------------> number alert(typeof c)------------> object alert(typeof d)------------> object alert(typeof e)------------> function alert(typeof f)------------> function 其中typeof返回的类型都是字符串形式,需注意,例如: alert(typeof a == "string") -------------> true alert(typeof a == String) ---------------> false 另外typeof 可以判断function的类型;在判断除Object类型的对象时比较方便。

2、判断已知对象类型的方法: instanceof
alert(c instanceof Array) ---------------> true alert(d instanceof Date) alert(f instanceof Function) ------------> true alert(f instanceof function) ------------> false 注意:instanceof 后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。

3、根据对象的constructor判断: constructor
alert(c.constructor === Array) ----------> true alert(d.constructor === Date) -----------> true alert(e.constructor === Function) -------> true 注意: constructor 在类继承时会出错 eg: function A(){}; function B(){}; A.prototype = new B(); //A继承自B var aObj = new A(); alert(aobj.constructor === B) -----------> true; alert(aobj.constructor === A) -----------> false; 而instanceof方法不会出现该问题,对象直接继承和间接继承的都会报true: alert(aobj instanceof B) ----------------> true; alert(aobj instanceof B) ----------------> true; 言归正传,解决construtor的问题通常是让对象的constructor手动指向自己: aobj.constructor = A; //将自己的类赋值给对象的constructor属性 alert(aobj.constructor === A) -----------> true; alert(aobj.constructor === B) -----------> false; //基类不会报true了;

4、通用但很繁琐的方法: prototype
alert(Object.prototype.toString.call(a) === ‘[object String]’) -------> true; alert(Object.prototype.toString.call(b) === ‘[object Number]’) -------> true; alert(Object.prototype.toString.call(c) === ‘[object Array]’) -------> true; alert(Object.prototype.toString.call(d) === ‘[object Date]’) -------> true; alert(Object.prototype.toString.call(e) === ‘[object Function]’) -------> true; alert(Object.prototype.toString.call(f) === ‘[object Function]’) -------> true; 大小写不能写错,比较麻烦,但胜在通用。

5、万能的方法:jquery.type()
如果对象是undefined或null,则返回相应的“undefined”或“null”。 jQuery.type( undefined ) === "undefined" jQuery.type() === "undefined" jQuery.type( window.notDefined ) === "undefined" jQuery.type( null ) === "null" 如果对象有一个内部的[[Class]]和一个浏览器的内置对象的 [[Class]] 相同,我们返回相应的 [[Class]] 名字。 (有关此技术的更多细节。 ) jQuery.type( true ) === "boolean" jQuery.type( 3 ) === "number" jQuery.type( "test" ) === "string" jQuery.type( function(){} ) === "function" jQuery.type( [] ) === "array" jQuery.type( new Date() ) === "date" jQuery.type( new Error() ) === "error" // as of jQuery 1.9 jQuery.type( /test/ ) === "regexp" 其他一切都将返回它的类型“object”。

9.console.log(1+‘2’)和console.log(1-‘2’)的打印结果
console.log(1+'2') //12 console.log(1-'2') //-1

10.Js的事件委托是什么,原理是什么 事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
原理:事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件。
11.如何改变函数内部的this指针的指向 1.bind:
  • fun.bind(thisArg[, arg1[, arg2[, …]]])
  • 他是直接改变这个函数的this指向并且返回一个新的函数,之后再次调用这个函数的时候this都是指向bind绑定的第一个参数。bind传餐方式跟call方法一致。
  • thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。
  • arg1, arg2, … 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
2.call:
  • fun.call(thisArg, arg1, arg2, …)
  • call跟apply的用法几乎一样,唯一的不同就是传递的参数不同,call只能一个参数一个参数的传入。
  • thisArg: 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
  • arg1, arg2, … 指定的参数列表
3.apply
  • apply则只支持传入一个数组,哪怕是一个参数也要是数组形式。最终调用函数时候这个数组会拆成一个个参数分别传入。
  • thisArg 在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
  • argsArray 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。
四.总结
  • 当我们使用一个函数需要改变this指向的时候才会用到callapplybind
  • 如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 …)
  • 如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 …])
    如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2…)
  • call和apply第一个参数为null/undefined,函数this指向全局对象,在浏览器中是window,在node中是global
12.列举几种解决跨域问题的方式,且说明原理 1.jsonp script标签是不受同源策略影响的,它可以引入来自任何地方的js文件。动态添加script
2、使用window.name来进行跨域 window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
3、使用HTML5中新引进的window.postMessage方法来跨域传送数据 window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
13.谈谈垃圾回收机制的方式及内存管理 一、垃圾回收机制—GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。
原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存
通常情况下有两种实现方式:标记清除和引用计数
  • 标记清除: js中最常用的垃圾回收方式就是标记清除。
当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。
  • 引用计数的含义是跟踪记录每个值被引用的次数。
当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为0的值所占用的内存。
二、内存管理 1)、Javascript引擎基础GC方案是(simple GC):mark and sweep(标记清除),即:
  • (1)遍历所有可访问的对象。
  • (2)回收已不可访问的对象。
2)、GC的缺陷
和其他语言一样,javascript的GC策略也无法避免一个问题:GC时,停止响应其他操作,这是为了安全考虑。而Javascript的GC在100ms甚至以上,对一般的应用还好,但对于JS游戏,动画对连贯性要求比较高的应用,就麻烦了。这就是新引擎需要优化的点:避免GC造成的长时间停止响应。
3)、GC优化策略
  • 1)分代回收(Generation GC)
    这个和Java回收策略思想是一致的。目的是通过区分“临时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对象”区(tenured generation),减少每次需遍历的对象,从而减少每次GC的耗时
  • 2)增量GC
    这个方案的思想很简单,就是“每次处理一点,下次再处理一点,如此类推”
14.写一个function ,清除字符串前后的空格
//重写trim方法 if(!String.prototype.trim){ String.prototype.trim = function(){ return this.replace(/^\s+/,"").replace(/\s+$/,""); } } //写fntrim去掉左右空格 function fntrim(str){ return str.replace(/^\s+/,"").replace(/\s+$/,""); }

15.js实现继承的方法有哪些 JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如下:
// 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };

1、原型链继承
核心:将父类的实例作为子类的原型
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.eat('fish')); console.log(cat.sleep()); console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true

特点:
  1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
  2. 父类新增原型方法/原型属性,子类都能访问到
  3. 简单,易于实现
缺点:
  1. 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
  2. 无法实现多继承
  3. 来自原型对象的所有属性被所有实例共享(来自原型对象的引用属性是所有实例共享的)(详细请看附录代码:[示例1](javascript:void(0))
  4. 创建子类实例时,无法向父类构造函数传参
2、构造继承
**核心:**使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; }// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true

特点:
  1. 解决了1中,子类实例共享父类引用属性的问题
  2. 创建子类实例时,可以向父类传递参数
  3. 可以实现多继承(call多个父类对象)
缺点:
  1. 实例并不是父类的实例,只是子类的实例
  2. 只能继承父类的实例属性和方法,不能继承原型属性/方法
  3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
3、实例继承
**核心:**为父类实例添加新特性,作为子类实例返回
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; }// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false

特点:
  1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
  1. 实例是父类的实例,不是子类的实例
  2. 不支持多继承
4、拷贝继承
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; }// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true

特点:
  1. 支持多继承
缺点:
  1. 效率较低,内存占用高(因为要拷贝父类的属性)
  2. 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
5、组合继承
**核心:**通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true

特点:
  1. 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
  2. 既是子类的实例,也是父类的实例
  3. 不存在引用属性共享问题
  4. 可传参
  5. 函数可复用
缺点:
  1. 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
6、寄生组合继承
**核心:**通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super(); })(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true Cat.prototype.constructor = Cat; // 需要修复下构造函数

特点:
  1. 堪称完美
缺点:
  1. 实现较为复杂
16.判断一个变量是否是数组,有哪些办法 1、在ECMAScript5标准中Array类增加了一个静态方法isArray,我们可以直接用Array.isArray来判断变量是否是数组。
Array.isArray([1,2,3]) //此处返回true
2、但是某些比较老的浏览器,比如IE8及以下,没有实现Array的isArray方法,那么就需要换一种方式来判断:
Object.prototype.toString.call([1,2,3]) //返回字符串:’[object Array]’
那么我们定义一个函数来实现数组判断
function isArray (value) {if(Object.prototype.toString.call(value) === '[object Array]') {return true}return false}

3、index of
var arr=new Array([“b”,2,“a”,4,“test”]);
17.let ,const ,var 有什么区别
  • let 和 const 定义的变量不会出现变量提升,而 var 定义的变量会提升。
  • let 和 const 是JS中的块级作用域
  • let 和 const 不允许重复声明(会抛出错误)
  • let 和 const 定义的变量在定义语句之前,如果使用会抛出错误(形成了暂时性死区),而 var 不会。
  • const 声明一个只读的常量。一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)
18.箭头函数与普通函数有什么区别
    1. 箭头函数是匿名函数,不能作为构造函数,不能使用new
    1. 箭头函数不绑定arguments,取而代之用rest参数…解决
    1. 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
    1. 箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。
    1. 箭头函数没有原型属性
    1. 箭头函数不能当做Generator函数,不能使用yield关键字
19.随机取1-10之间的整数 Math.floor([Math.random]*10+1)
20.new操作符具体干了什么
  • 创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型
  • 属性和方法被加入到this引用的对象中
  • 新创建的对象由this所引用,并且最后隐式的返回this
21.Ajax原理
  • Ajax的原理简单来说是在用户和服务器之间加了—个中间层(AJAX引擎),通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据
  • Ajax的过程只涉及JavaScriptXMLHttpRequestDOMXMLHttpRequestajax的核心机制
//1. 创建连接 var xhr = null; xhr = new XMLHttpRequest() // 2. 连接服务器 xhr.open('get', url, true) // 3. 发送请求 xhr.send(null); // 4. 接受请求 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ success(xhr.responseText); } else { // fail fail && fail(xhr.status); } } }

22.模块化开发怎么做
  • 立即执行函数,不暴露私有成员
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();

23.异步加载Js的方式有哪些
  • defer,只支持IE
  • async
  • 创建script,插入到DOM中,加载完毕后callBack
24.xml和 json的区别
  • 数据体积方面
    • JSON相对于XML来讲,数据的体积小,传递的速度更快些。
  • 数据交互方面
    • JSONJavaScript的交互更加方便,更容易解析处理,更好的数据交互
  • 数据描述方面
    • JSON对数据的描述性比XML较差
  • 传输速度方面
    • JSON的速度要远远快于XML
25.webpack如何实现打包的
  • WebPack是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web开发中所用到的HTMLJavascriptCSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源
26.常见web安全及防护原理
  • sql注入原理
    • 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
  • 总的来说有以下几点
    • 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等
    • 永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取
    • 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
    • 不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息
XSS原理及防范
  • Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点
XSS防范方法
  • 首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”; ”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击
XSS与CSRF有什么区别吗?
  • XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次CSRF攻击,受害者必须依次完成两个步骤
  • 登录受信任网站A,并在本地生成Cookie
  • 在不登出A的情况下,访问危险网站B
CSRF的防御
  • 服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数
  • 通过验证码的方法
27.用过哪些设计模式
  • 工厂模式:
    • 工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法
    • 主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字
  • 构造函数模式
    • 使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,该模式与工厂模式的不同之处在于
    • 直接将属性和方法赋值给this对象;
28.为什么要同源限制
  • 源策略指的是:协议,域名,端口相同,同源策略是一种安全协议
  • 举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。
29.offsetWidth/offsetHeight,clientWidth/clientHeight与scrollWidth/scrollHeight的区别
  • offsetWidth/offsetHeight返回值包含content + padding + border,效果与e.getBoundingClientRect()相同
  • clientWidth/clientHeight返回值只包含content + padding,如果有滚动条,也不包含滚动条
  • scrollWidth/scrollHeight返回值包含content + padding + 溢出内容的尺寸
30.javascript有哪些方法定义对象
  • 对象字面量:var obj = {};
  • 构造函数:var obj = new Object();
  • Object.create():var obj = Object.create(Object.prototype);

    推荐阅读