前端的常见的面试试题
- Javascript有哪些打开一个页面的方式?
1.超链接<a href="http://www.100sucai.com/" title="100素材网">Welcome</a>
等效于js代码
window.location.href="http://www.100sucai.com/"; //在同当前窗口中打开窗口
2.超链接<a href="http://www.100sucai.com/" title="100素材网" target="_blank">Welcome</a>
等效于js代码
window.open("http://www.100sucai.com/");//在另外新建窗口中打开窗口
window.history.back(-1);返回上一页
window.open(sURL [,vArguments] [,sFeatures]) 新页面
window. showmodaldialog(sURL[, vArguments] [,sFeatures]) 模态对话框
window.showModelessDialog(sURL[, vArguments] [,sFeatures]) 非模态对话框
- Javascript如何做到在子页面中调用父页面的js函数或者全局变量(如test()函数,test()变量)?
window.opener.test();Window.opener.test= “abc”;
2.1 window.parent与window.opener的区别?
有这样一个需求,弹出一个新窗口 并从该新页面的select选择框中选择需要的类别,再返回到之前的父窗口页面的某个文本框中。这里就要用到window.parent和window.opener如题两种方法都是javascript调用父窗口的方法。1、window.parent是iframe页面调用父窗口对象 比如:parent.jsp 里面有一个文本框<input id="username" value=""><iframe scrolling="auto" src="PLUGIN/CMS/children.jsp"id="rightFrame_id" frameborder="0" name="rightFrame"></iframe>当要在children.jsp里为parent.jsp页面中的username文本框赋值时,可在children.jsp里这样写:window.parent.document.getElementById("username").value = "hello"对应jquery版本为:$("#username",window.parent.document).val("hello");2、window.opener是window.open打开的子页面调用父页面对象 比如a.jsp<input type="button" οnclick="show();" value="测试" /> <input type="text" id="myhobby" value="">function show(){window.open("PLUGIN/CMS/shop/b.jsp", "ModifyAcce",'width=500,height=400,toolbar=no,status=no,location=no,scrollbars=yes,resizable=yes'); } 想要在b.jsp里为a.jsp中的myhobby赋值,可以这样写:window.opener.document.getElementById("myhobby").value = "hello"; 对应jquery版本为:$("#myhobby",window.opener.document).val("hello"); 总结: window.parent中的parent表示父窗口,比如一个A页面利用iframe或frame调用B页面,那么A页面就是B页面的parent。 B页面可以通过parent访问A页面。window.opener中的opener表示谁打开我的,比如一个A页面利用window.open弹出了B页面,那么A页面就是B页面的opener。 B页面可以通过opener访问A页面。
- Javascript中定时执行如何实现?
setTimeout();定时执行,执行一次。clearTimeout(定时器对象名)结束setInterval();定时执行,一直执行。clearInterval(定时器对象名)结束两种区别:setTimeout();定时执行,执行一次。clearTimeout(定时器对象名)结束;setInterval();定时执行,一直执行。clearInterval(定时器对象名)结束
- innerHTML和outerHTML的区别是什么?
innerHTML取页面元素标签内部的内容,outerHTML取包含元素标签的内容,如<a href=”test.jsp”>test</a>,innerHTML取到test,outerHTML取到<ahref=”test.jsp”>test</a>.
- javascript如何做到页面局部刷新?
使用AJAX。原理:获取一个请求对象,向指定url发送请求,当请求完成时(状态4),获取到请求返回内容,并将内容填充到页面局部。
- 请列举数组和字符串的的可用方法?
数组常见方法1.push(参数1): 向数组尾部添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。var arr=[0,1,2,3,4];console.log(arr);//只要后面向数组添加了元素,打印出来的都是添加元素后的数组[ 1, 2, 3 ,4],var len =arr.push(5);//向数组尾部添加一个元素5,并返回新添加的数组的长度length console.log(len)//打印出来的是长度6 console.log(arr)//打印出来的数组是添加元素之后的数组[ 1, 2, 3 ,4],2.pop(): 删除数组的最后一个元素,并返回该元素。该方法会改变原数组。var arr=[1,2,3];console.log(arr);//打印出来的是删除元素后的数组[1,2]var b=arr.pop();//返回的是删除后的元素 console.log(b);//打印出来的是最后一个元素3 console.log(arr);//打印出来的是删除元素后的数组3.unshift():在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。var arr = ['a', 'b', 'c'];var len=arr.unshift('x'); //4 console.log(arr);//['x', 'a', 'b', 'c']4.shift():删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。var arr = ['a', 'b', 'c'];var b=arr.shift() //'a' console.log(arr)//['b', 'c'] shift()方法还可以遍历并清空一个数组。var list = [1, 2, 3, 4, 5, 6];varitem;while (item =list.shift()) {console.log(item);//遍历数组,循环的输出1,2,3,4,5,6.遍历完之后清空数组 }console.log(list);//数组为空[]5.valueOf():返回数组的本身。var arr = [1, 2, 3];var aarr=arr.valueOf();console.log(aarr);//[1, 2, 3]6.indexOf():返回指定元素在数组中出现的位置,如果没有出现则返回-1。var arr = ['a', 'b', 'c'];var n=arr.indexOf('c') //2 console.log(n);//打印出来的是2var m=arr.indexOf('y'); //-1 console.log(m);indexOf方法还可以接受第二个参数,表示搜索的开始位置。var nm=arr.indexOf('a', 1) //nm的值为 -17.toString():返回数组的以逗号分割的字符串形式。var arr = [1, 2, 3];var str=arr.toString() //"1,2,3" console.log(str);var arr = [1, 2, 3, [4, 5, 6]];var str1=arr.toString() ; //"1,2,3,4,5,6" console.log(str1);8.join():以参数作为分隔符,将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔var arr = [1, 2, 3, 4];var str=arr.join()console.log(str);//"1,2,3,4"var str1=arr.join(' ')console.log(str1);//“1 2 3 4”var str2=arr.join('|')console.log(str2)//"1 | 2 | 3 | 4"9.concat():用于多个数组的合并。它将新数组的成员,添加到原数组的尾部,然后返回一个合并后的新数组,原数组不变。1 var arr = [1,2,3];2 var arr1 = arr.concat([4,5,6]);3 console.log(arr1); //[1,2,3,4,5,6]10.reverse():用于颠倒数组中元素的顺序,返回改变后的数组。注意,该方法将改变原数组。1 var arr = ['a', 'b', 'c'];var arr1=arr.reverse() //["c", "b", "a"] console.log(arr1)//["c", "b", "a"] console.log(arr)//也是["c", "b", "a"]11.slice():用于截取原数组的一部分,返回一个截取的新数组,原数组不变。slice(start,end)它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。var arr = ['a', 'b', 'c'];arr.slice(0) //["a", "b", "c"] arr.slice(1) //["b", "c"] arr.slice(1, 2) //["b"] arr.slice(2, 6) //["c"] arr.slice()//["a", "b", "c"] 无参数返回原数组 arr.slice(-2) //["b", "c"] 参数是负数,则表示取倒数的后两位 arr.slice(-3) //[“a”,”b”,”c”] 表示 取倒数的后三位 arr.slice(-2, -1) //["b"] 表示取倒数的第二位,-1不包含在范围内 arr.slice(-3,-2)//表示取倒数的第三位 arr.slice(-3,-1)//表示取倒数的第二位和第三位12.splice():删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。splice(start,delNum,addElement1,addElement2,...)第一个参数是删除的起始位置,第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。var arr = ['a', 'b', 'c', 'd', 'e', 'f'];arr.splice(4, 2) //["e", "f"] 从原数组4号位置,删除了两个数组成员 console.log(arr)//["a", "b", "c", "d"]var arr = ['a', 'b', 'c', 'd', 'e', 'f'];arr.splice(4, 2, 1, 2) //["e", "f"] 原数组4号位置,删除了两个数组成员,又插入了两个新成员 console.log(arr)//["a", "b", "c", "d", 1, 2]var arr = ['a', 'b', 'c', 'd', 'e', 'f'];arr.splice(-4, 2) //["c", "d"] 起始位置如果是负数,就表示从倒数位置开始删除,从倒数第四个位置开始删除,并删除两个var arr = [1, 1, 1];arr.splice(1, 0, 2) //[] 如果只插入元素,第二个参数可以设为0 conlose.log(arr)//[1, 2, 1, 1]var arr = [1, 2, 3, 4];arr.splice(2) //[3, 4] 如果只有第一个参数,等同于将原数组在指定的位置开始删除,直到数组最后 console.log(arr)//[1, 2]13.sort():对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。1. ['d', 'c', 'b', 'a'].sort() //['a', 'b', 'c', 'd']2.[4, 3, 2, 1].sort() //[1, 2, 3, 4]3.[11, 101].sort() //[101, 11]4. [10111, 1101, 111].sort() //[10111, 1101, 111] 上面代码的最后两个例子,需要特殊注意。sort方法不是按照大小排序,而是按照对应字符串的字典顺序排序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以101排在11的前面。如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身又接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。var arr = [10111, 1101, 111];arr.sort(function (a, b) {return a -b;})//[111, 1101, 10111]var arr1 =[{ name:"张三", age: 30},{ name:"李四", age: 24},{ name:"王五", age: 28}]arr1.sort(function (o1, o2) {return o1.age -o2.age;})//[//{ name: "李四", age: 24 },//{ name: "王五", age: 28 },//{ name: "张三", age: 30 }//]10.map():参数是一个函数,对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。原数组不变。返回的是对原数组中的成员进行调用函数后的新数组。var numbers = [1, 2, 3];var arr1=numbers.map(function (n) {return n + 1;});//arr1 = [2, 3, 4]//numbers = [1, 2, 3] 上面代码中,numbers数组的所有成员都加上1,组成一个新数组返回,原数组没有变化。11.filter():参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。var arr = [1, 2, 3, 4, 5]arr.filter(function (elem) {return (elem > 3);})//[4, 5],返回的是原数组中符合条件的成员 JS字符串常见用法字符串字符串就是一个或多个排列在一起的字符,放在单引号或双引号之中。'abc'"abc"length属性js里的字符串类似于数组,都是一个一个字符拼凑在一起组成的,因此可以用length属性取得字符串的长度var str = "hello"str.length;//5 字符串常用的一些方法1. charAt()str.charAt(n)=> 返回字符串的第 n 个字符,如果不在 0~str.length-1之间,则返回一个空字符串。var str = "javascript";str.charAt(2); //'v' str.charAt(12); //'' 字符串的操作在js中非常频繁,也非常重要。以往看完书之后都能记得非常清楚,但稍微隔一段时间不用,便会忘得差不多,记性不好是硬伤啊。。。今天就对字符串的一些常用操作做个整理,一者加深印象,二者方便今后温习查阅。String对象属性(1) length属性length算是字符串中非常常用的一个属性了,它的功能是获取字符串的长度。当然需要注意的是js中的中文每个汉字也只代表一个字符,这里可能跟其他语言有些不一样var str = 'abc';console.log(str.length);(2) prototype属性prototype在面向对象编程中会经常用到,用来给对象添加属性或方法,并且添加的方法或属性在所有的实例上共享。因此也常用来扩展js内置对象,如下面的代码给字符串添加了一个去除两边空格的方法:String.prototype.trim=function(){return this.replace(/^\s*|\s*$/g, '');}String对象方法1.获取类方法(1) charAt()stringObject.charAt(index)charAt()方法可用来获取指定位置的字符串,index为字符串索引值,从0开始到string.leng –1,若不在这个范围将返回一个空字符串。如var str = 'abcde';console.log(str.charAt(2)); //返回c console.log(str.charAt(8)); //返回空字符串 (2) charCodeAt()stringObject.charCodeAt(index)charCodeAt()方法可返回指定位置的字符的Unicode编码。charCodeAt()方法与charAt()方法类似,都需要传入一个索引值作为参数,区别是前者返回指定位置的字符的编码,而后者返回的是字符子串。var str = 'abcde';console.log(str.charCodeAt(0)); //返回97 (3) fromCharCode()String.fromCharCode(numX,numX,…,numX)fromCharCode()可接受一个或多个Unicode值,然后返回一个字符串。另外该方法是String 的静态方法,字符串中的每个字符都由单独的数字Unicode编码指定。String.fromCharCode(97, 98, 99, 100, 101) //返回abcde2.查找类方法(1) indexOf()stringObject.indexOf(searchvalue,fromindex)indexOf()用来检索指定的字符串值在字符串中首次出现的位置。它可以接收两个参数,searchvalue表示要查找的子字符串,fromindex表示查找的开始位置,省略的话则从开始位置进行检索var str = 'abcdeabcde';console.log(str.indexOf('a')); //返回0 console.log(str.indexOf('a', 3)); //返回5 console.log(str.indexOf('bc')); //返回1 (2) lastIndexOf()方法stringObject.lastIndexOf(searchvalue,fromindex)lastIndexOf()语法与indexOf()类似,它返回的是一个指定的子字符串值最后出现的位置,其检索顺序是从后向前。var str = 'abcdeabcde';console.log(str.lastIndexOf('a')); //返回5 console.log(str.lastIndexOf('a', 3)); //返回0 从第索引3的位置往前检索 console.log(str.lastIndexOf('bc')); //返回6 (3) search()方法stringObject.search(substr)stringObject.search(regexp)search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。它会返回第一子字符个匹配的串的起始位置,如果没有匹配的,则返回-1。var str = 'abcDEF';console.log(str.search('c')); //返回2 console.log(str.search('d')); //返回-1 console.log(str.search(/d/i)); //返回3 (4) match()方法stringObject.match(substr)stringObject.match(regexp)match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。如果参数中传入的是子字符串或是没有进行全局匹配的正则表达式,那么match()方法会从开始位置执行一次匹配,如果没有匹配到结果,则返回null。否则则会返回一个数组,该数组的第0个元素存放的是匹配文本,除此之外,返回的数组还含有两个对象属性index和input,分别表示匹配文本的起始字符索引和stringObject 的引用(即原字符串)。var str = '1a2b3c4d5e';console.log(str.match('h')); //返回null console.log(str.match('b')); //返回["b", index: 3, input: "1a2b3c4d5e"] console.log(str.match(/b/)); //返回["b", index: 3, input: "1a2b3c4d5e"] 如果参数传入的是具有全局匹配的正则表达式,那么match()从开始位置进行多次匹配,直到最后。如果没有匹配到结果,则返回null。否则则会返回一个数组,数组中存放所有符合要求的子字符串,并且没有index和input属性。var str = '1a2b3c4d5e';console.log(str.match(/h/g)); //返回null console.log(str.match(/\d/g)); //返回["1", "2", "3", "4", "5"]3.截取类方法(1) substring()stringObject.substring(start,end)substring()是最常用到的字符串截取方法,它可以接收两个参数(参数不能为负值),分别是要截取的开始位置和结束位置,它将返回一个新的字符串,其内容是从start处到end-1处的所有字符。若结束参数(end)省略,则表示从start位置一直截取到最后。var str = 'abcdefg';console.log(str.substring(1, 4)); //返回bcd console.log(str.substring(1)); //返回bcdefg console.log(str.substring(-1)); //返回abcdefg,传入负值时会视为0 (2) slice()stringObject.slice(start,end)slice()方法与substring()方法非常类似,它传入的两个参数也分别对应着开始位置和结束位置。而区别在于,slice()中的参数可以为负值,如果参数是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1指字符串的最后一个字符。var str = 'abcdefg';console.log(str.slice(1, 4)); //返回bcd console.log(str.slice(-3, -1)); //返回ef console.log(str.slice(1, -1)); //返回bcdef console.log(str.slice(-1, -3)); //返回空字符串,若传入的参数有问题,则返回空 (3) substr()stringObject.substr(start,length)substr()方法可在字符串中抽取从start下标开始的指定数目的字符。其返回值为一个字符串,包含从 stringObject的start(包括start所指的字符)处开始的length个字符。如果没有指定 length,那么返回的字符串包含从start到stringObject的结尾的字符。另外如果start为负数,则表示从字符串尾部开始算起。var str = 'abcdefg';console.log(str.substr(1, 3)) //返回bcd console.log(str.substr(2)) //返回cdefg console.log(str.substr(-2, 4)) //返回fg,目标长度较大的话,以实际截取的长度为准4.其他方法(1) replace()方法stringObject.replace(regexp/substr,replacement)replace()方法用来进行字符串替换操作,它可以接收两个参数,前者为被替换的子字符串(可以是正则),后者为用来替换的文本。如果第一个参数传入的是子字符串或是没有进行全局匹配的正则表达式,那么replace()方法将只进行一次替换(即替换最前面的),返回经过一次替换后的结果字符串。var str = 'abcdeabcde';console.log(str.replace('a', 'A'));console.log(str.replace(/a/, 'A'));如果第一个参数传入的全局匹配的正则表达式,那么replace()将会对符合条件的子字符串进行多次替换,最后返回经过多次替换的结果字符串。var str = 'abcdeabcdeABCDE';console.log(str.replace(/a/g, 'A')); //返回AbcdeAbcdeABCDE console.log(str.replace(/a/gi, '$')); //返回$bcde$bcde$BCDE (2) split()方法stringObject.split(separator,howmany)split()方法用于把一个字符串分割成字符串数组。第一个参数separator表示分割位置(参考符),第二个参数howmany表示返回数组的允许最大长度(一般情况下不设置)。var str = 'a|b|c|d|e';console.log((str.split(" ") )//空格用来分割每个英语单词 console.log(str.split('|')); //返回["a", "b", "c", "d", "e"] console.log(str.split('|', 3)); //返回["a", "b", "c"] console.log(str.split('')); //返回["a", "|", "b", "|", "c", "|", "d", "|", "e"] 也可以用正则来进行分割var str = 'a1b2c3d4e';console.log(str.split(/\d/)); //返回["a", "b", "c", "d", "e"] (3) toLowerCase()和toUpperCase()stringObject.toLowerCase()stringObject.toUpperCase()toLowerCase()方法可以把字符串中的大写字母转换为小写,toUpperCase()方法可以把字符串中的小写字母转换为大写。var str = 'JavaScript';console.log(str.toLowerCase());//返回javascript console.log(str.toUpperCase());//返回JAVASCRIPT
- 请实现,鼠标点击页面中的任何标签,alert该标签的名称?
var el = document.getElementsByTagName('body'); el[0].οnclick=function(event){ evt=event||window.event;var selected=evt.target||evt.srcElement; alert(selected.tagName);}
- 完成一个正则表达式,验证输入是否为合法的邮箱号?
\d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^$分别是什么?\d:匹配数字 \w:匹配字母或数字或下划线或汉字 \s:匹配任意的空白符 [a-zA-z0-9]:匹配任意字母和数字 \b:匹配单词的开始或结束 . :匹配除换行符以外的任意字符*:重复零次或更多次+:重复一次或更多次?:重复零次或一次 x{3}:重复三次x^$:匹配行的开始处和结束处 贪婪模式和非贪婪模式指什么?贪婪模式:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配*懒惰模式**:匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复 代码 写一个函数trim(str),去除字符串两边的空白字符 代码:function trim(str){newstr= str.replace(/^\s*|\s*$/,'');returnnewstr}var a = 'asdas dasdasd'console.log(trim(a)) 使用实现 addClass(el, cls)、hasClass(el, cls)、removeClass(el,cls),使用正则//提示: el为dom元素,cls为操作的class, el.className获取el元素的class 代码://提示: el为dom元素,cls为操作的class, el.className获取el元素的class function addClass(el, cls) {if (!hasClass(el, cls)) {el.className+= " " +cls;}}function hasClass(el, cls) {var reg = new RegExp('\\b' + cls + '\\b', 'g');returnreg.test(el.className);}function removeClass(el, cls) {var reg = new RegExp('\\b' + cls + '\\b', 'g'),tmp= node.className.replace(reg, '').replace(/\s{2,}/g, ' '); //把两个以上的空格替换为一个空格el.className =trim(tmp);} 写一个函数isEmail(str),判断用户输入的是不是邮箱 代码:function isEmail(str){reg= /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/greturnreg.test(str)}console.log(isEmail('a'))//falseconsole.log(isEmail('123@qq.com'))//trueconsole.log(isEmail('zzzzzzzdadasdqweqwedq@163.com'))//trueconsole.log(isEmail('w-eqwdasd@qq.com'))//true 写一个函数isPhoneNum(str),判断用户输入的是不是手机号 代码:function isPhone(str){reg= /^1[3|5|7|8]\d{9}$/greturnreg.test(str)}console.log(isPhone('110'))//falseconsole.log(isPhone('13893000000'))//trueconsole.log(isPhone('1881333900'))//falseconsole.log(isPhone('12345678901'))//falseconsole.log(isPhone('17045678901'))//true 写一个函数isValidUsername(str),判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线) 代码:function isValidUsername(str){reg= /^[0-9a-zA-Z|_]{6,20}$/greturnreg.test(str)}console.log(isValidUsername('111111!'))//falseconsole.log(isValidUsername('zxw1111_'))//trueconsole.log(isValidUsername('zxw_2131242153243241'))//trueconsole.log(isValidUsername('zxw$$aweeqweqw'))//falseconsole.log(isValidUsername('zxczxwZZX'))//true 写一个函数isValidPassword(str), 判断用户输入的是不是合法密码(长度6-20个字符,包括大写字母、小写字母、数字、下划线至少两种) 代码:function isValidPassword(str){if(str.length<6||str.length>20){return false}if(/[^a-zA-Z0-9_]/.test(str)){return false}if(/(^[a-z]+$|^[A-Z]+$|^\d+$|^_+$)/.test(str)){return false}return true}console.log(isValidPassword('zxw1992513')) 写一个正则表达式,得到如下字符串里所有的颜色(#121212)var re = /*正则...*/var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2"alert( subj.match(re) )//#121212,#AA00ef 代码:var re = /#[0-9a-fA-F]{6}/g/*正则...*/var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2"alert( subj.match(re) )//#121212,#AA00ef 下面代码输出什么? 为什么?改写代码,让其输出hunger, world.var str = 'hello "hunger" , hello "world"';var pat = /".*"/g;str.match(pat); 因为是贪婪模式,会把最外""中内容输出,即输出"hunger" , hello "world"代码://方法一var str = 'hello "hunger" , hello "world"';var pat = /"\w*"/g;str.match(pat); console.log(str.match(pat))//方法二var str = 'hello "hunger" , hello "world"';var pat = /".*?"/g;str.match(pat); console.log(str.match(pat)) 补全如下正则表达式,输出字符串中的注释内容. (可尝试使用贪婪模式和非贪婪模式两种方法)str= '.. <!-- My -- comment \n test --> .. <!----> ..'re= /.. your regexp ../str.match(re)//'<!-- My -- comment \n test -->', '<!---->' 代码://贪婪模式str = '.. <!-- My -- comment \n test --> .. <!----> ..'re= /<!--{FNXX==XXFN}*-->/gstr.match(re)//'<!-- My -- comment \n test -->', '<!---->' console.log(str.match(re))//非贪婪模式str = '.. <!-- My -- comment \n test --> .. <!----> ..'re= /<!--[\w\W]*?-->/gstr.match(re)//'<!-- My -- comment \n test -->', '<!---->' console.log(str.match(re)) 补全如下正则表达式var re = /*your regexp*/var str = '<> <a href="/"> <input type="radio" checked> <b>'str.match(re)//'<a href="/">', '<input type="radio" checked>', '<b>' 代码:var re = /<{FNXX==XXFN}+>/gvar str = '<> <a href="/"> <input type="radio" checked> <b>'str.match(re)//'<a href="/">', '<input type="radio" checked>', '<b>'console.log(str.match(re))
- 实现垂直居中的css?
利用css实现垂直居中的方法1.如果是单行文本。(子元素是块级元素,则设置子元素的line-height等于父元素的高,可使子元素垂直居中与父元素)<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{width: 500px;height: 500px;background: gray;} #wrapper p{line-height: 500px;//行高=父级的height,垂直居中。text-align: center;//水平居中 }</style> </head> <body> <div id="wrapper"><p>这是一段要垂直水平居中的文字!</p> </div> </body> </html>2、对于已知高度的块级子元素,子元素采用绝对定位,{position: absolute;top:50%;height: 300px; margin-top: -150px;} 另一种的绝对定位:子元素不管是块级,行内。未知高度的子元素,设置子元素{ position: absolute;top:50%;left:50%;width:100%; transform:translate(-50%,-50%);text-align: center;} 适用:绝对定位为页面布局没有影响的情况下可以使用,并且子级的高度是已知的。<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{position: relative;//父级 width: 500px;height: 500px;background: gray;} #wrapper p{position: absolute;//子级用绝对定位top:50%;//先定位到50%的位置height: 300px;//已知的高度margin-top: -150px;//往上提本身高度的一半 }</style> </head> <body> <div id="wrapper"><p>这是一段要垂直水平居中的文字!这是一段要垂直水平居中的文字!</p> </div> </body> </html>3、对于已知块级子级元素的高度,而且不能用绝对定位来布局的情况,(利用一个空的div让其width为100%,高度为父元素的50%。适用:对于绝对布局有影响,不能适用position:absolute的元素,可以用以上这种方法,思路是:用一个块级元素,设置已知大小,在让其高度达到父级容器的一半大小,再把要居中的元素往上提半个高度。跟方法2同理。<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{background: gray;width: 500px;height: 500px;text-align: center;overflow: hidden;} #null{//利用一个空的div让其width为100%,高度父元素的50%width: 100%;height:50%;background: yellow;}#content {height: 100px;margin:-50px;}</style> </head> <body> <div id="wrapper"><div id="null"></div><div id="content">居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧中吧~</div> </div> </body> </html>4、垂直居中一张图片(行内元素)。(vertical-align:middle用在子元素,父级元素上使用line-height与height同高)4.1还是有点没懂为什么使用<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{width: 800px;height: 800px;background: gray;text-align: center;line-height: 800px;//跟父级一样高 }#wrapper img{vertical-align: middle;}</style> <body> </head> <div id="wrapper"><img src="http://img0.bdstatic.com/img/image/2016ss1.jpg" alt=""> </div> </body> </html>4.2 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{width: 800px;height: 800px;background: gray;text-align: center;}#wrapper img{vertical-align: middle;} #wrapper #block{background: blue;line-height:800px;width:0;}</style> </head> <body> <div id="wrapper"><img src="http://img0.bdstatic.com/img/image/2016ss1.jpg" alt=""><img id="block"> </div> </body> </html>然后,有些同学可能会有疑问,行内元素那么多。为什么你要用<img>标签呢!? 嗯嗯,也可以用其他行内元素,这里我用<span>来试一试给大家看:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{width: 800px;height: 800px;background: gray;text-align: center;}#wrapper img{vertical-align: middle;} #wrapper #block{background: blue;line-height: 800px;//跟父级一样高 }</style> </head> <body><div id="wrapper"><img src="http://img0.bdstatic.com/img/image/2016ss1.jpg" alt=""><span id="block"></span> </div> </body> </html>5.在不管子元素是(行内,或者块级)子元素未知高度的情况下,父级元素使用 {display: table-cell; vertical-align: middle; text-align: center; }或者使用 {display: flex; justify-content:center; align-items:Center;}子级实现垂直居中。<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{background: gray;width: 500px;height: 500px;text-align: center;display: table-cell;vertical-align: middle;} #content {}</style> </head> <body> <div id="wrapper"><span id="content">居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~</span> </div> </body> </html> 6.当子元素为(行内,块级)元素时,子元素使用绝对定位和0 {height:700px;//当子元素为块级元素时,还可以设置高度width:50%;height:50%;background: #fff;overflow: auto; margin: auto; position: absolute; top:0; left: 0; bottom: 0; right: 0; } 看代码:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{position: relative;background: gray;width: 800px;height: 800px; }#content {width:50%;height:50%;background: #fff;overflow: auto; margin: auto; position: absolute; top:0; left: 0; bottom: 0; right: 0; }</style> </head> <body> <div id="wrapper"><span id="content">tytyty</span> </div> </body> </html>注意:如果是行内元素为img,省略掉width:50%;height:50%;也可<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style>#wrapper{position: relative;background: gray;width: 800px;height: 800px; }#content {position: absolute;top:0;bottom:0;left:0;right:0;margin:auto;}</style> </head> <body> <div id="wrapper"><img id="content" src="http://img0.bdstatic.com/img/image/2016ss1.jpg" alt=""> </div> </body> </html>
- 以下代码的运行结果是什么,如果希望看到控制台每隔一秒输出一个数字,连续输出1-9,应该如何修改代码?
for(var i=0;i<10;i++){setTimeout(function(){console.log(i);},1000); } 答案是:打印了10次10,setTimeOut是异步进行的。
for (var i = 0; i < 5; i++) {(function (j) { // j = isetTimeout(function () {console.log(new Date, j);}, 1000);})(i);}以上使用自执行方法解决,只有一个作用:创建一个独立的作用域。打印结果:
Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 0
VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 1
VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 2
VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 3
VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 4以上在同一时间分别打印0,1,2,3,4
for(var i=0;i<=3;i++){
setTimeout(function() {
console.log(i)
}, 10);
}
答案:打印4次4
这道题涉及了异步、作用域、闭包?
settimeout是异步执行,10ms后往任务队列里面添加一个任务,只有主线上的全部执行完,才会执行任务队列里的任务,当主线执行完成后,i是4,所以此时再去执行任务队列里的任务时,i全部是4了。对于打印4次是:
每一次for循环的时候,settimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了4次,就放了4次,当主线程执行完成后,才进入任务队列里面执行。(注意:for循环从开始到结束的过程,需要维持几微秒或几毫秒。)当我把var 变成let 时for(let i=0;i<=3;i++){setTimeout(function(){console.log(i) },10);}打印出的是:0,1,2,3当解决变量作用域,因为for循环头部的let不仅将i绑定到for循环快中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。
查了一下百度的一个答案:
setTimeout是一次执行函数,这里是10ms后执行,仅仅执行一次;for(var i=0;i<=3;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),setTimeout里面的function是有setTimeout的定时触动的,也就是10ms后执行,也就是说i从0~3时,一共执行了4次的setTimeout()函数,此时的i的值是4,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是4了,所以相继打印4次i.
JavaScript中var、let、const区别?
简单来说是: let是修复了var的作用域的一些bug,变的更加好用。let是更好的var。var的作用域是函数作用域由var定义的变量,它作用域在一个函数体内,而不是我们其他语言理解的大括号{ }内。而let是块级别(大括号括起来的内容)
const声明的变量只可以在声明时赋值,不可随意修改,这是最大的特点。
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); //6
console.log(a[6]); // function(){console.log(i)}
既然循环结束后,数组a的每一项都是function(){console.log(i)},那么a[6]()输出是6是怎么实现的?难道let保存了10个状态?
这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
var a = [];for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};}
a[6](); // 10
上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。
也就是说,循环结束后,数组a的每一项都是function(){console.log(i)}。在执行a[6]函数前,此时i的值已经是10了。
- 编写一个javascript函数,消除下面数组里的重复元素,var arr = [1,5,8,4,7,4,9,6,8,7];
- 输出结果
var name = "The window";var object ={name:"My Object",getNameFunc: function () {returnfunction () {return this.name;//闭包没有访问外层函数的变量,闭包里的this没有具体指向。}} }console.log(object.getNameFunc()());
)打印的是:"The window";
- 输出结果
function Obj(){}var a = new Obj(),b = newObj(); Obj.prototype.age= 20; Obj.prototype.name={"firstName":"Jhon"} b.age= 10; b.name.firstName= "Bob"; alert(a.age);//20 alert(a.name.firstName);//Bob
function Obj(){}
var a = new Obj(),b = new Obj();
Obj.prototype.age = 20;
Obj.prototype.name = {
"firstName":"Jhon"
}
b.age = 10;
b.name = {firstName:"yys"};
alert(a.age);//20
alert(a.name.firstName);//Jhonalert(b.name.firstName);//yys
从原理跟你说起。首先Js有一隐性规则,js中任何变量(属性)都是基于Object这个构造函数创建的,所以Js没有严格的类型区分,因为所有的类型都可以是Object。又,在js中Object是可以用点运算符(.)来为对象新增属性或方法的,所以你的b也是一个Object,自然也就能新增属性,然而这个新增的属性是一个自身属性,没有任何特殊。(语法糖?)
b.name.firstName = "Bob";b.name.firstName 是对原型上属性的引用,那么你对它操作的时候,实际上就是对原型上操作。但是b.name = {firstName:"yys"};//这句话是为对象添加一个自身的属性并赋值。这就不同了,相当于给person1这个对象实例添加了一个属性,不是给原型添加。关键在于=。
由此我们也可以看出另外一层意思:如果对象实例中包含和原型对象中同名的属性或方法,则对象实例中的该同名属性或方法会屏蔽原型对象中的同名属性或方法。原因就是“首先在该对象中查找该属性,若找到,返回该属性值;”
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age.push('3');
console.log(person1.age, person2.age); // ['1', '2', '3'] , ['1', '2', '3']
person1.age = ['1'];
console.log(person1.age, person2.age); // ['1'] , ['1', '2', '3']
从原理跟你说起。首先Js有一隐性规则,js中任何变量(属性)都是基于Object这个构造函数创建的,所以Js没有严格的类型区分,因为所有的类型都可以是Object。又,在js中Object是可以用点运算符(.)来为对象新增属性或方法的,所以你的persion1也是一个Object,自然也就能新增属性,然而这个新增的属性是一个自身属性,没有任何特殊。(语法糖?)
person1.age.push('3');
是对属性的引用,那么你对它操作的时候,实际上就是对原型上操作。但是
person1.age = ['1'];//这句话是为对象添加一个自身的属性并赋值。
这就不同了,相当于给person1这个对象实例添加了一个属性,不是给原型添加。关键在于=。
age在prototype上定义所以是类属性 所以可以正常访问它 但是后面那个赋值实际上是设置了一个实例属性 这是不能共享的 通常对类的改写应该写成修改prototype属性 就是说你第一个也应该写Person.prototype.age.push()。
一开始, person1.age与person2.age指向同一个引用,即Person.prototype.age所指向的那个对象。person1.age = ['1'];
这一步后,person1.age指向一个新建的数组对象,然而person2.age不变依然指向Person.prototype.age指代的对象。之后对person1的操作都是对['1']数组对象的操作,而不是对其原型链上对象的操作,肯定就不会改变了,因为都不是一个对象。
因为 Array 是引用类型,多个相同的引用副本指向的是同一个 Array 对象。既然对同一个对象进行 push,其他引用该对象的自然也就变了。而重新赋值后相当于新建了一个与原型不同的 Array 对象,其他对象并没有此 Array 的引用,所以对它的修改不会影响到原型中的 Array 对象。
当我们需要读取对象的某个属性时,都会执行一次搜索。首先在该对象中查找该属性,若找到,返回该属性值;否则,到[[prototype]]指向的原型对象中继续查找。
由此我们也可以看出另外一层意思:如果对象实例中包含和原型对象中同名的属性或方法,则对象实例中的该同名属性或方法会屏蔽原型对象中的同名属性或方法。原因就是“首先在该对象中查找该属性,若找到,返回该属性值;”
1.
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age = ['1'];
console.log(person1.age, person2.age); // [ "1", "3" ] ,[ "1", "2" ]
person1.age.push('3');
console.log(person1.age, person2.age); // [ "1", "3" ] ,[ "1", "2" ]
2.
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age = ['1'];
console.log(person1.age, person2.age); // [ "1" ] ,[ "1", "2", "3" ]
person2.age.push('3');
console.log(person1.age, person2.age); //[ "1" ] ,[ "1", "2", "3" ]
转载于:https://www.cnblogs.com/susan-home/p/8658045.html
前端的常见的面试试题相关推荐
- 前端一面常见vue面试题汇总
说说你对 proxy 的理解,Proxy 相比于 defineProperty 的优势 Object.defineProperty() 的问题主要有三个: 不能监听数组的变化 :无法监控到数组下标的变 ...
- 新浪时金php面试题,关于面试PHP常见的面试试题
二十一世纪企业之间的竞争说到底是人才的竞争,是人力资源的竞争,人力资源管理便成为企业管理的重要组成部分,而招聘又是人力资源管理的第一关,即企业如何面试.下面是小编为你整理的,希望你喜欢. 1. 基本知 ...
- 前端不常见25k+面试题(持续更新)
这一套面试题可能和网上看到的都不太一样,如果你都能答出来,那你就是25k+的水平了 1.苹果手机字体的锯齿怎么实现平滑 -webkit-font-smoothing: subpixel-antiali ...
- 前端最常见的面试题整理
自我简介 你好,面试官,我叫XX,有两年的开发经验,来应聘前端开发工程师这一岗位,上一家公司是XXX时代科技有限公司,期间主要负责pc端网站的开发,还有微信小程序和app的维护,开发的技术栈主要就是v ...
- 前端一些常见的面试题
前端面试题 Happy coding. new的原理 function Foo (name, age) {this.name = name;this.age = age;this.class = 'c ...
- 2021最前端最常见的面试题
假如给你一个复杂的功能让你实现,有什么思路写好这个功能? 解决问题之前需要理解问题,找出问题的主干 要求解的是什么? 需要实现的复杂功能是什么? 已知什么? 这个功能的实现逻辑什么是什么? 要满足哪些 ...
- Web前端人员如何面试?常见vue面试题有哪些?
Web前端人员如何面试?常见vue面试题有哪些?vue是一套用于构建用户界面的渐进式JavaScript框架,也是初创项目的首选前端框架.很多企业在招聘前端工程师时都会考察其对vue的了解,接下来小编 ...
- Web前端经典面试试题(二)
上次由于时间有限只分享了一部分的前端面试题,所以本篇继续分享前端经典面试试题 一. 栈和队列的区别? 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的. 队列先进先出,栈先进后出. 栈 ...
- 2018最新Web前端经典面试试题及答案
本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题,并且都给出了我在网上收集的答案.马上就要过春节了,开年就是崭新的一年,相信很多的前端开发者会有一些跳槽的悸动,通过对本篇知识 ...
最新文章
- macOs下全局安装npm包的设置问题
- Zookeeper 服务注册与发现02——服务消费者
- Docker 容器启动失败日志分析方法,启动sonic容器实例simple时未报错运行一会又停止的问题排查实例演示
- 爬虫项目(二)---采集从03月02号以来的世界各国疫情数据
- win10系统崩溃怎么修复_系统崩溃怎么重装系统图文教程
- HDU 3400 Line belt (三分)
- label之间展示间距_工法样板如何做?碧桂园质量工法样板展示区做法标准
- 深入浅出MySql索引
- 切比雪夫多项式(Chebyshev Polynomials)
- xcode打包ipa配置手动配置证书
- 数据结构 停车场管理系统
- 在团购网上空手赚钱项目,你敢做就敢赚!
- 玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入
- [论文阅读](图像/视频质量评价系列)
- js爬取:bili播放列表,右下角建立红底白字下载按钮,保存为csv格式到本地
- datagrip 导出数据库表结构
- squid+icap测试配置
- Jmeter压力测试简单教程(包括服务器状态监控)-----转载自lsoqvle 的博客(https://blog.csdn.net/cbzcbzcbzcbz/article/details/780)
- dhcp租约(dhcp租约时间可设置为永久吗)
- Angular 实现树形菜单(多级菜单)功能模块
热门文章
- 在mathtype中怎么打出花体字母
- rebase in git
- PDE11 wave equation: d'Alembert examples
- mysql数据库中 pri_mysql数据库part2
- mysql pdo支持_使php支持pdo_mysql
- 托管系统的mysql设计_PHP+MySQL托管中心管理系统的设计与实现
- delphi 获取操作系统版本_Ubuntu 20.04 LTS已可通过Windows 10应用商店获取
- 从RCNN到SSD,深度学习目标检测算法盘点
- yolo3做行人检测+deep-sort做匹配,端对端做多目标跟踪
- php 读取数据库信息,php读取数据库信息的几种方法