// 构造函数
function Foo(name, age) {
this.name = name;
};
Foo.prototype.alertName = function () {
alert(this.name);
};
// 创建实例
var f = new Foo("zhangsan");
f.printName = function () {
console.log(this.name);
};
// 测试
f.alertName();
f.printName();
循环对象自身的属性
var item;
for (item in f) {
/*高级浏览器已经在forin中屏蔽了来自原型的属性,但是在这里建议
大家加上这个判断,保证程序的健壮性。*/
if (f.hasOwnProperty(item)) {
console.log(item);
}
}
原型链
// 构造函数
function Foo(name, age) {
this.name = name;
};
Foo.prototype.alertName = function () {
alert(this.name);
};
// 创建实例
var f = new Foo("zhangsan");
f.printName = function () {
console.log(this.name);
};
// 测试
f.alertName();
f.printName();
f.toString(); //要去f.__proto__.__proto__中查找
instanceof
用于判断引用类型属于哪个构造函数的方法。
作用域和闭包
题目
说一下对变量提升的理解
说明this 几种不同的使用场景
创建10个a标签,点击的时候弹出来对应的序号
如何理解作用域
实际开发中闭包的应用
解答
函数声明与函数表达式的区别
fn();
functionfn() { }; //函数声明
fn1(); //会报错
var fn1 = function () {}; //函数表达式
执行上下文
console.log(a); //undefined
var a = 100;
fn("zhangsan"); //"zhangsan",20
function fn(name, age) {
age = 20;
console.log(name, age);
var age;
};
范围:一段< script >或者一个函数
全局:变量定义、函数声明
函数:变量定义、函数声明,this,arguments
this
this 要在执行时才能确认值,定义时无法确认
作为构造函数执行
作为对象属性执行
作为普通函数执行
call apply bind
// 作为构造函数执行
function Foo(name) {
this.name = name;
};
var f = new Foo("zhangsan");
// 作为对象属性执行
var obj = {
name: "A",
printName: function () {
console.log(this.name);
}
}
obj.printName();
// 作为普通函数执行
functionfn() {
console.log(this);
};
fn();
// call apply
function fn1(name, age) {
alert(name);
console.log(this);
};
fn1.call({x: 100}, "zhangsan", 20); //工作中常用这个
fn1.apply({x: 100}, ["zhangsan", 20]);
// bind 只能用函数表达式,函数声明会报错
var fn2 = function (name, age) {
alert(name);
console.log(this);
}.bind({y: 200});
fn2("zhangsan", 20);
作用域
没有块级作用域
只有函数和全局作用域
// 无块级作用域
if (true) {
var name = "zhangsan";
}
console.log(name); // zhangsan
// 函数和全局作用域
var a = 100;
functionfn() {
var a = 200;
console.log("fn", a);
};
console.log("global", a);
fn();
作用域链
var a = 100;
functionfn() {
var b = 200;
//当前作用域没有定义的变量,即“自由变量”
console.log(a);
console.log(b);
};
fn();
另一个例子
var a = 100;
functionF1() {
var b = 200;
functionF2() {
var c = 300;
console.log(a); //自由变量
console.log(b); //自由变量
console.log(c);
};
F2()
};
F1();
闭包
函数作为返回值
functionF1() {
var a = 100;
// 返回一个函数(函数作为返回值)
returnfunction () {
console.log(a); // 自由变量,父作用域寻找
}
}
// f1 得到一个函数
var f1 = F1();
var a = 200; //一个函数的作用域,是它定义时候的作用域,而不是它执行时候的作用域
f1();
闭包的使用场景
函数作为返回值(上一个demo)
函数作为参数传递(自己思考)
函数作为参数传递
functionF1() {
var a = 100;
returnfunction () {
console.log(a);
}
}
var f1 = F1();
function F2(fn) {
var a = 200;
fn(); //定义时的作用域,而非执行时的作用域
}
F2(f1);
function formatDate(dt) {
if (!dt) {
dt = new Date();
}
var year = dt.getFullYear();
var month = dt.getMonth();
var date = dt.getDate();
if (month < 10) {
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
return year + "-" + month + "-" + date;
}
var dt = new Date();
var formatDate = formatDate(dt);
console.log(formatDate);
获取随机数,要求是长度一致的字符串格式
var random = Math.random();
random = random + "0000000000"; //后面加上10个零
random = random.slice(0, 10);
console.log(random);
写一个能遍历数组和对象的forEach 函数
functionforEach(obj, fn) {
var key;
if (obj instanceof Array) {
// 准确判断是不是数组
obj.forEach(function (item, index) {
fn(index, item);
})
} else {
// 不是数组就是对象
for (key in obj) {
fn(key, obj[key]);
}
}
}
var arr = [1, 2, 3];
// 注意:这里参数的顺序换了,为了和对象的遍历格式一致
forEach(arr, function (index, item) {
console.log(index, item);
});
var obj = {x: 100, y: 200};
forEach(obj, function (key, value) {
console.log(key, value);
});
html 是 xml 的一种特殊类型
DOM 可以理解为:浏览器拿到的html代码,结构化一个浏览器能识别并且js可操作的一个模型而已。
DOM 节点操作
获取DOM 节点
Prototype
Attribute
获取DOM 节点
var div1 = document.getElementById("div"); //元素
var divList = document.getElementsByTagName("div"); //集合
var containerList = document.getElementsByClassName(".container"); //集合
var pList = document.querySelectorAll("p"); //集合
Prototype
var pList = document.querySelectorAll("p");
var p = pList[0];
console.log(p.style.width); //获取样式
p.style.width = "100px"; //修改样式
console.log(p.className); //获取class
p.className = ".para"; //修改class
// 获取nodeName 和 nodeType
console.log(p.nodeName);
console.log(p.nodeType);
Attribute
var pList = document.querySelectorAll("p");
var p = pList[0];
p.getAttribute("data-name");
p.setAttribute("data-name", "imooc");
p.getAttribute("style");
p.setAttribute("style", "font-size:30px");
DOM 结构操作
新增节点
获取父元素
获取子元素
删除节点
新增节点
var div1 = document.getElementById("div");
// 添加新节点
var p1 = document.createElement("p");
p1.innerHTML = "this is p1";
div1.appendChild(p1); //添加新创建的元素
// 移动已有节点
var p2 = document.getElementById("p2");
div1.appendChild(p2);
获取父元素和子元素
var div1 = document.getElementById("div");
var parent = div1.parentElement;
var child = div1.childNodes;
div1.removeChild(child[0]);
删除节点
var div1 = document.getElementById("div");
var child = div1.childNodes;
div1.removeChild(child[0]);
BOM 操作
BOM:Brower Object Model
题目
如何检测浏览器的类型
拆解URL 的各个部分
解答
如何检测浏览器的类型?
var ua = navigator.userAgent;
var isChrome = ua.indexOf("Chrome");
console.log(isChrome);
navigator
var ua = navigator.userAgent;
var isChrome = ua.indexOf("Chrome");
console.log(isChrome);
var p1 = document.getElementById("p1");
var body = document.body;
p1.addEventListener("click", function (e) {
// e.stopPropagation();
alert("激活");
});
body.addEventListener("click", function (e) {
alert("取消");
});
var div1 = document.getElementById("div1");
div1.addEventListener("click", function (e) {
var target = e.target;
if (target.nodeName === "A") {
alert(target.innerHTML);
}
});
使用代理
var div1 = document.getElementById("div1");
bindEvent(div1, "click", "a", function (e) {
console.log(this.innerHTML)
});
不使用代理
var div1 = document.getElementById("div1");
var a = document.getElementById("a1");
bindEvent(div1, "click", function (e) {
console.log(a.innerHTML)
});
Ajax和跨域
Ajax
var xhr = new XMLHttpRequest();
xhr.open("GET", "/api", false);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText);
}
}
};
xhr.send(null);