文章目录
- 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.简述同步和异步的区别
- 同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
- 异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容
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, … 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
- fun.call(thisArg, arg1, arg2, …)
- call跟apply的用法几乎一样,唯一的不同就是传递的参数不同,call只能一个参数一个参数的传入。
- thisArg: 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
- arg1, arg2, … 指定的参数列表
- 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
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)、Javascript引擎基础GC方案是(simple GC):mark and sweep(标记清除),即:
- (1)遍历所有可访问的对象。
- (2)回收已不可访问的对象。
和其他语言一样,javascript的GC策略也无法避免一个问题:GC时,停止响应其他操作,这是为了安全考虑。而Javascript的GC在100ms甚至以上,对一般的应用还好,但对于JS游戏,动画对连贯性要求比较高的应用,就麻烦了。这就是新引擎需要优化的点:避免GC造成的长时间停止响应。
3)、GC优化策略
- 1)分代回收(Generation GC)
这个和Java回收策略思想是一致的。目的是通过区分“临时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对象”区(tenured generation),减少每次需遍历的对象,从而减少每次GC的耗时 - 2)增量GC
这个方案的思想很简单,就是“每次处理一点,下次再处理一点,如此类推”
//重写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
特点:
- 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
- 父类新增原型方法/原型属性,子类都能访问到
- 简单,易于实现
- 要想为子类新增属性和方法,必须要在
new Animal()
这样的语句之后执行,不能放到构造器中 - 无法实现多继承
- 来自原型对象的所有属性被所有实例共享(来自原型对象的引用属性是所有实例共享的)(详细请看附录代码:[示例1](javascript:void(0))
- 创建子类实例时,无法向父类构造函数传参
**核心:**使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
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中,子类实例共享父类引用属性的问题
- 创建子类实例时,可以向父类传递参数
- 可以实现多继承(call多个父类对象)
- 实例并不是父类的实例,只是子类的实例
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
**核心:**为父类实例添加新特性,作为子类实例返回
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
特点:
- 不限制调用方式,不管是
new 子类()
还是子类()
,返回的对象具有相同的效果
- 实例是父类的实例,不是子类的实例
- 不支持多继承
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
特点:
- 支持多继承
- 效率较低,内存占用高(因为要拷贝父类的属性)
- 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
**核心:**通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
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
特点:
- 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
- 既是子类的实例,也是父类的实例
- 不存在引用属性共享问题
- 可传参
- 函数可复用
- 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
**核心:**通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
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;
// 需要修复下构造函数
特点:
- 堪称完美
- 实现较为复杂
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 声明一个只读的常量。一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)
-
- 箭头函数是匿名函数,不能作为构造函数,不能使用new
-
- 箭头函数不绑定arguments,取而代之用rest参数…解决
-
- 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
-
- 箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。
-
- 箭头函数没有原型属性
-
- 箭头函数不能当做Generator函数,不能使用yield关键字
20.new操作符具体干了什么
- 创建一个空对象,并且
this
变量引用该对象,同时还继承了该函数的原型 - 属性和方法被加入到
this
引用的对象中 - 新创建的对象由
this
所引用,并且最后隐式的返回this
Ajax
的原理简单来说是在用户和服务器之间加了—个中间层(AJAX
引擎),通过XmlHttpRequest
对象来向服务器发异步请求,从服务器获得数据,然后用javascrip
t来操作DOM
而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据Ajax
的过程只涉及JavaScript
、XMLHttpRequest
和DOM
。XMLHttpRequest
是aja
x的核心机制
//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
- 数据体积方面
JSON
相对于XML
来讲,数据的体积小,传递的速度更快些。
- 数据交互方面
JSON
与JavaScript
的交互更加方便,更容易解析处理,更好的数据交互
- 数据描述方面
JSON
对数据的描述性比XML
较差
- 传输速度方面
JSON
的速度要远远快于XML
WebPack
是一个模块打包工具,你可以使用WebPack
管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web
开发中所用到的HTML
、Javascript
、CSS
以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack
有对应的模块加载器。webpack
模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源
sql
注入原理- 就是通过把
SQL
命令插入到Web
表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
- 就是通过把
- 总的来说有以下几点
- 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双
"-"
进行转换等 - 永远不要使用动态拼装SQL,可以使用参数化的
SQL
或者直接使用存储过程进行数据查询存取 - 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
- 不要把机密信息明文存放,请加密或者
hash
掉密码和敏感的信息
- 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双
Xss(cross-site scripting)
攻击指的是攻击者往Web
页面里插入恶意html
标签或者javascript
代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cookie
中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点
- 首先代码里对用户输入的地方和变量都需要仔细检查长度和对
”<”,”>”,”; ”,”’”
等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag
弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击
XSS
是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF
是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次CSRF
攻击,受害者必须依次完成两个步骤- 登录受信任网站
A
,并在本地生成Cookie
- 在不登出
A
的情况下,访问危险网站B
- 服务端的
CSRF
方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数 - 通过验证码的方法
- 工厂模式:
- 工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法
- 主要好处就是可以消除对象间的耦合,通过使用工程方法而不是
new
关键字
- 构造函数模式
- 使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,该模式与工厂模式的不同之处在于
- 直接将属性和方法赋值给
this
对象;
- 源策略指的是:协议,域名,端口相同,同源策略是一种安全协议
- 举例说明:比如一个黑客程序,他利用
Iframe
把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript
读取到你的表单中input
中的内容,这样用户名,密码就轻松到手了。
offsetWidth/offsetHeight
返回值包含content + padding + border,效果与e.getBoundingClientRect()相同clientWidth/clientHeight
返回值只包含content + padding,如果有滚动条,也不包含滚动条scrollWidth/scrollHeight
返回值包含content + padding + 溢出内容的尺寸
- 对象字面量:
var obj = {};
- 构造函数:
var obj = new Object();
- Object.create():
var obj = Object.create(Object.prototype);
推荐阅读
- 前端面试|【1.1w字】面试常问Javascript 事件循环、同步异步、宏微任务,彻底明白原来这么简单
- javascript|JavaScript理论题(一)
- 排序算法|JS优化版(二叉搜索树第k大节点)
- javascript|睡前做几道JavaScript理论练习题吧
- vue.js|Vue练习题--不定时分享
- JS DY6 数组
- js dy5 (函数,事件,对象)
- js dy3 感觉需要注意的地方(包含循环)
- js dy2 感觉需要注意的地方(包括数据类型和逻辑分支)