文章目录
简述单向绑定与双向绑定
单向绑定是数据流单一,双向数据绑定主要用于需要实时反映用户输入的场合
JavaScript中的模块化
名称 | 实现 | 其他 |
---|---|---|
AMD | 浏览器端,require.js实现 | 依赖前置 |
CMD | 浏览器端,see.js实现 | 依赖就近 |
CommonJS | 服务器端,NodeJs实现 |
作用域与闭包的理解
当参数为普通数据类型时
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){
console.log(i); // 0,1,2,3,4
},0);
})(i);
}
for(var i = 0; i < 5; i++){
setTimeout(function(){
console.log(i);// 4,4,4,4,4
},0);
}
当参数为对象时
for (var i = {j:0}; i < 5; i.j++) {
(function(i) {
setTimeout(function(){
console.log(i.j);//4,4,4,4,4
}, 0);
})(i);
}
引用类型变量,加上自执行函数,仍然不行的原因:
for(var i = {j: 0}; i.j < 5; i.j++){
(function(i) {
setTimeout(function(){
console.log(i.j); // 0,1,2,3,4
},0);
})(JSON.parse(JSON.stringify(i)));
}
代码分析:
- 知识点1:这道题涉及到,for循环中,var申明变量没有块级作用域。会导致for循环结束后,以前的值,无法保留下来。
- 知识点2:JS里面的语句执行顺序。总体是从上往下执行,调用function时会将它放入栈中,遇到 setTimeOut()会放入队列中。function按照先进后出的顺序执行。而setTimeOut会在所有可以执行的JS语句都执行完毕后,再按照先进先出的顺序执行计时器。
对于没有块级作用域,通过闭包的原理解决。
网上有人说,例子二输出一样是因为没有块级作用域,但我认为不太对,因为我们已经用自执行函数解决了没有块级作用域的问题。
(1)JSON.stringify:将JS数据结构转化为JSON字符串
(2)JSON.parse :将JSON字符串解析为JS数据结构
检测一下是否弄懂了
var data = [];
for(var i = 0; i < 3; i++){
data[i] = (function(num){
return function(){
console.log(num);
}
})(i);
}
data[0](); //0
data[1](); //1
data[2](); //2
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i++);
}, 1000);
}
// 0,1,2
按址引用
var setPerson=function(person){
person.name="kevin";
//console.log("1", person);
person = {name:"nick"};
//console.log(2, person);
};
//console.log(person);
var person={name:"alan"};
//console.log(person);
setPerson(person);
//person = {name:"nick"};
//console.log("外", person);
alert(person.name);
答案:Kevin
详解:
- JS里面的参数都是
按值传递
的。调用setPerson时,将实参
person_A的地址赋值
给了函数里面的形参
person_B。(加上后缀,好区分) - person.name=“kevin”,因为此时person_B与person_A的指向一样,person_B通过地址修改了内存里面的对象的name属性。
- person = {name:“nick”} 语句,开辟一个新的对象,将新地址值赋值给person_B,注意此时,person_B和person_A的指向已经不一样了。这一语句不会影响到person_A
- 通过person_A访问到的对象的name属性——Kevin
数组的迭代类方法
var array1=Array(3);
array1[0]=2;
var result=array1.map(element => "1");
console.log(result);
答案:[ “1”, null, null ]
详解:
- map函数,按照原始数组元素顺序依次操作元素
- return 语句 结束本轮循环,并将 return语句后面的表达式结果,保存到一个新数组里边
- 返回值:新数组,与原数组等长
- 是否改变原数据:否
|| 运算符
var a= 2018<0 || typeof(2018+"");
console.log(a);
答案:string
详解:
|| 运算符 真前假后
下列关于line-height,说法正确的是
A line-height设置150%或1.5都是一样的效果
B 在Inline元素设置line-height不会生效
C 设定line-height的值少于font-size 的值,元素高度为font-size的值
D line-height属性会被继承
答案:A D
line-height详解
以下代码运行结果为
var elements = ['Fire','wind','Rain'];
console.log(elements.join(','));
答案:Fire,wind,Rain
以下代码运行结果为
var execFunc = function(){
console.log("executed");
};
setTimeout(execFunc,0);
console.log("changed");
execFunc = function(){
console.log("another executed");
}
答案:changed executed
能阻止事件冒泡的方法
A e.preventDefault()
B event.cancelBubble = true
C event.returnValue = false
D e.stopPragation()
答案: B D
分析:DOM中的事件对象 event.stopPropagation()可以阻止事件的传播.,取消进一步的事件冒泡或者捕获
IE中的事件对象 cancelBubble属性值为true,可以取消事件冒泡。
preventDefault() 阻止事件的默认行为,只有cancelabel属性的值设为true时,才可以使用preventDefalut.
下面选项中给submitan按钮绑定click事件,正确的是
A btn.addEventListener(“click”,fun,false);
B btn.dispatchEvent(“click”,fun,true);
C btn.attachEvent(“onclick”,fun);
D btn.detachEvent(“onclick”,fun);
答案:ABC
分析: DOM2级事件绑定: addEventListener有三个参数:第一个参数表示事件名称(不含 on,如 “click”);第二个参数表示要接收事件处理的函数;第三个参数为 useCapture。
IE用了attachEvent(),和detachEvent(),接收两个参数,事件名称和事件处理程序函数。由于IE8及以前只支持事件冒泡;通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
attachEvent(event, function):event 必须。字符串,指定事件名。注意: 使用 “on” 前缀。 例如,使用 “onclick” ,而不是使用 “click”
btn.detachEvent(“onclick”,handler); /IE下移除侦听器/
事件触发器也是分为高级浏览器和IE两派,而dispatchEvent正是用于高级浏览器的事件触发。 dispatchEvent是作为高级浏览器(如chrome、Firfox等)的事件触发器来使用的。
单词逆序
对于一个字符串,请设计一个算法,只在字符串的单词间做逆序调整,也就是说,字符串由一些由空格分隔的部分组成,你需要将这些部分逆序。
给定一个原字符串A,请返回逆序后的字符串。例,输入"I am a boy!", 输出"boy! a am I"
function reverseString (str){
var arr = str.split(/\s/g);
console.log(arr.reverse().join(" "));
}
reverseString("I am a boy!");
硬币划分
有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n <= 100000),有多少种组合可以组成n分钱?
字符串全排列
对K个不同字符的全排列组成的数组, 面试官从中随机拿走了一个, 剩下的数组作为输入, 请帮忙找出这个被拿走的字符串? 比如[“ABC”, “ACB”, “BAC”, “CAB”, “CBA”] 返回 “BCA”
字符串加密和解密
输入的字符串规则:由数字和26个英文字母的大小写组成
加密规则:
- 数字 +1 ,9变为0
- 字母 变为下一个字母 ,并转变大小写,z变为A ,Z变为a
function change(str){
var code_A = "A".charCodeAt(0); //65
var code_a = "a".charCodeAt(0); //97
var arr = str.replace(/\s/g, "").split("");
var newArr = arr.map((item, index) => {
if(isNaN(Number(item))){
var code_item = item.charCodeAt(0);
if(code_item >= code_A && code_item < code_a){
// 字符为 大写
var new_code = code_item - code_A + code_a + 1;
if(new_code === code_a + 26){
new_code = code_a;
}
item = String.fromCharCode(new_code);
return item;
} else {
// 字符为小写
var new_code = code_item - code_a + code_A + 1;
if(new_code === code_A + 26){
new_code = code_A;
}
item = String.fromCharCode(new_code);
return item;
}
} else {
item = Number(item);
item += 1;
if(item === 10){
item = 0;
}
return item;
}
});
console.log(newArr.join(""));
}
change("12A39z0Z"); //23b40A1a
进制转换
涉及到数字的计算,不采用JS,采用Java
import java.util.Scanner;
public class Main{
public static void mian(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int jinzhi = in.nextInt();
zhuanHuan(n, jinzhi);
}
public void zhuanHuan(int n,int jinzhi){
String str = "";
while(n!=0){
str = n%jinzhi + str;
n = n/jinzhi;
}
System.out.println(str);
}
}
封装函数 f,使 f 的 this 指向指定的对象
function bindThis(f, oTarget) {
return function (){
return f.apply(oTarget, arguments);
}
}
解题思路
call,apply,bind 都是改变上下文的,但是call apply是立即执行的,而bind是返回一个改变上下文的函数副本
获取 url 中的参数
- 指定参数名称,返回该参数的值 或者 空字符串
- 不指定参数名称,返回全部的参数对象 或者 {}
- 如果存在多个同名参数,则返回数组
需要明确
- 指定参数,返回的是一个对象
- 一个参数时,对象属性值为参数值
- 多个同名参数,对象属性值为一个数组,这个数组包含了所有的参数值
- 不指定参数,返回的是一个对象,或者 空字符串
我一开始理解成了,没有指定参数时,返回对象或者空字符串,指定参数后若参数只有一个则返回参数值,若多个参数同名则返回数组。于是,分情况讨论,代码一大片,最后还错了!
emmmm,清楚的了解题目的意思特别的重要。否则只能是南辕北辙!
function getUrlParam(sUrl, sKey) {
var paramArr = sUrl.split('?')[1].split('#')[0].split('&'); // 取出每个参数的键值对放入数组
const obj = {};
paramArr.forEach(item => {
const [key, value] = item.split('='); // 取出数组中每一项的键与值
if(obj[key] === void 0){ // 表示第一次遍历这个元素,直接添加到对象上面
obj[key] = value
} else{
obj[key] = [].concat(obj[key], value); // 表示不是第一次遍历说明这个键已有,通过数组存起来。
}
});
return sKey === void 0 ? obj: obj[sKey] || ''
// 如果该方法为一个参数,则返回对象。
//如果为两个参数,sKey存在,则返回值或数组,否则返回空字符。
}
void 0
void 操作符,执行后面的语句后返回 undfined,那么,为何不直接用undefined呢?
在这道题使用undefined是完全可以的!
在实际开发中,推荐使用 void 0 为何?因为
- 占位少
- JS中,undefined 并不是保留字或者关键字,这意味着我们可以将undefined作为变量名进行赋值,会导致undefined不是一个纯正的undefined,变成了一个可以是任意数值的变量
查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:
oNode1 和 oNode2 在同一文档中,且不会为相同的节点
function commonParentNode(oNode1, oNode2) {
for(;;oNode1 = oNode1.parentNode){
if(oNode1.contains(oNode2)){
return oNode1;
}
}
}
转载:https://blog.csdn.net/weixin_44048286/article/details/101429905