Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:
任何一个函数都有一个原型属性:prototype,该属性是一个指针,指向一个对象,该对象称之为原型对象(可以使用这个原型对象帮助我们在js中实现继承)
原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。
调用构造函数实例化对象,都拥有一个内部属性,指向原型对象。其实例对象能够访问原型对象上的所有属性和方法
简言之:每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数
//任何一个函数都有一个原型属性:prototype
function f1() {}
console.log(f1);
//prototype对普通函数没用,对构造函数才有用
//构造函数是"对象工厂",是用来创建对象的
//对象也叫做“实例”,实例:实际案例 是具体的。
//js中没有“类”的概念,他是基于原型的语言,所以可以将构造函数当成类
//构造函数必须使用“new”来调用,普通函数不用
//new的过程就是类的实例化过程,就是创建一个对象的过程
//创建类的过程,就叫“类的实例化”
// 声明一个构造函数
function User(name, email) {
//1. 创建出一个新对象,用this来表示(伪代码)
// const this = new User;
//2. 初始化对象,给这个对象添加自定义属性,用来和其他实例进行区分
this.name = name;
this.email = email;
//3. 返回这个对象
// return this;
}
const user = new User("admin", "admin@php.cn");
console.log(user instanceof User);
console.log(user);
user.__proto__.salary = 8899;
console.log(user.salary);
const user1 = new User("tp", "tp@php.cn");
console.log(user1);
console.dir(User);
//实例的原型永远指向他的构造函数的原型,实例的原型从构造函数的原型继承成员(属性/方法)
console.dir(user1.__proto__ === User.prototype);
//需要被所有的类实例共享的成员,应该写在构造函数的原型上
User.prototype.nation = "CHINA";
console.log(user.nation, user1.nation);
//属性通常不应该共享,是区分不同对象的标志,方法更适合共享
User.prototype.show = function () {
return {name:this.name,email:this.email,salary:this.salary};
}
console.log(user.show());
console.log(user1.show());
//构造函数模拟类
const User = function (name, email) {
this.name = name;
this.email = email;
};
//原型方法
User.prototype.show = function () {
return { name: this.name, email: this.email };
}
const user = new User("tp", "tp@php.cn");
console.log(user.show());
// es6 中的类来改写
class User1 {
// 类的构造方法
constructor(name, email) {
this.name = name;
this.email = email;
}
//原型方法,使用类实例/对象来调用
show() {
return { name: this.name, email: this.email,age: this.#age};
}
//静态方法:不需要通过对象调用,直接用类调用
static fetch(){
//静态方法中的this指向类
// return { name: this.name, email: this.email };
return this.hello(this.userName);
}
static userName = 'xxx';
static hello(name){
return 'hello '+name;
}
//私有成员,只能在本类中使用,类外,子类中都不能用
#age = 40;
//声明为私有主要是访问限制
//访问器属性
set age(value){
if (value >= 18 && value <= 60){
this.#age = value;
} else {
throw new Error("年龄必须在18-60之间");
}
}
get age(){
return this.#age;
}
}
const user1 = new User1("tp", "tp@php.cn");
console.log(user1.show());
//静态方法用类调用比如 Array.of(),Array.form()
console.log(User1.fetch());
//访问私有成员
console.log(user1.age);
// user1.age=80;
// console.log(user1.age);
// 类的继承
class Child extends User1 {
//子类扩展父类的功能,可以拥有自己的属性或者方法
// 子类中可以访问父类的构造方法,原型方法,静态方法,不能访问父类的私有成员
constructor(name, email,gender) {
// this.name = name;
// this.email = email;
// super()调用父类构造方法,确定this指向
super(name,email);
this.gender = gender;
}
show(){
return { name: this.name, email: this.email ,gender:this.gender};
}
}
const child = new Child("yy","yy@php.cn","yy_yy");
console.log(child.show());
// 类中成员:构造方法,原型方法,静态方法,私有方法
// 继承 extends,super()
总结:js中类是构造函数的语法糖;class 中 constructor 关键字;子类 扩展 extends ,以及子类中constructor 中的super()
类中不同方法的调用:原型方法使用实例调用,静态方法使用类调用,静态方法使用static 关键字
使页面动起来的必要条件,获取元素
<ul id="list">
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
<li class="item">item4</li>
<li class="item">item5</li>
</ul>
<img src="../1223/static/images/jddog.png" alt="">
<a href="../1223/static/images/jddog.png">连接</a>
<form action="">
<input type="text">
</form>
<script>
//使用css选择器是最直观的
//1. 获取满足条件的所有元素
const lis = document.querySelectorAll("#list li");
console.log(lis);
//Nodelist 是浏览器内置的集合类型,属性类数组
//Array.from(),[...rest],都可以转为真正的数组
let lisArr = Array.from(lis);
console.log(lisArr);
console.log([...lis]);
// Nodelist 可以直接用forEach()遍历
// lis.forEach(function (item, index, arr) {
// console.log(item, index, arr);
// });
// 一般只写第一个参数 拿到遍历的元素
// lis.forEach(function (item) {
// console.log(item);
// });
//使用箭头函数简写
// lis.forEach(item=>console.log(item));
let first = document.querySelectorAll("#list li:first-of-type");
console.log(first);
console.log(first[0]);
//2. 获取满足条件的第一个元素
first = document.querySelector("#list li");
console.log(first);
console.log("---------------------");
// 还有传统的方式
// document.getElementById()
// document.getElementsByTagName()
// document.getElementsByName()
// document.getElementsByClassName()
// console.log(document.getElementById("list"));
// console.log(document.getElementsByTagName("ul"));
// console.log(document.getElementsByTagName("li"));
// console.log(document.getElementsByClassName("item"));
// 有几个快捷方式,用来快速获取某一或者某一类元素
//html
// console.log(document.documentElement);
//head
console.log(document.head);
//body
console.log(document.body);
//title
console.log(document.title);
//forms
console.log(document.forms);
console.log(document.forms[0]);
console.log(document.forms.item(0));
console.log(document.images);
console.log(document.anchors);
</script>
总结:一招鲜吃遍天下 document.quyerySelector()
返回满足条件的第一个元素;document.quyerySelectorAll()
返回满足条件的一个元素集合。可以使用Array.from()
转化为数组,或者使用 …rest 语法:[...lis]
。一组快捷键需要记下
//html
console.log(document.documentElement);
//head
console.log(document.head);
//body
console.log(document.body);
//title
console.log(document.title);
//forms
console.log(document.forms);
console.log(document.forms[0]);
console.log(document.forms.item(0));
console.log(document.images);
<ul id="list">
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
<li class="item">item4</li>
<li class="item">item5</li>
</ul>
<script>
const ul =document.querySelector("#list");
//1. 创建元素
const li = document.createElement("li");
li.innerText='新增';
//parent.appendChild(childEl),父元素里添加新的子元素
ul.appendChild(li);
li.innerHTML=`<li style="color:red"> item6 </li>`;
let htmlStr="<li style='color:blue'>item7</li>";
ul.insertAdjacentHTML("beforeend",htmlStr);
// 如果大量添加元素应该使用文档片段完成
// const frag = document.createdocumentfragment();
const frag = new DocumentFragment;
for (let i=0;i<5;i++){
const li = document.createElement("li");
li.textContent="item8-"+(i+1);
//将生成的节点先临时挂载到文档片段中
frag.appendChild(li)
}
ul.appendChild(frag);
htmlStr = `
<li style="color:violet"> demo1 </li>
<li style="color:violet"> demo2 </li>
<li style="color:violet"> demo3 </li>
<li style="color:violet"> demo4 </li>
`;
ul.insertAdjacentHTML("afterbegin",htmlStr);
//用元素不用字符串
ul.insertAdjacentElement("afterbegin",li);
ul.insertAdjacentHTML("afterbegin","<li>itme test</li>");
//2.更新
let h3 = document.createElement("h3");
h3.innerHTML =" hello ";
document.querySelector("li:nth-of-type(3)").replaceWith(h3);
// console.log(document.querySelector("ul > li:last-of-type"));
ul.replaceChild(h3, document.querySelector("ul > li:last-of-type"));
//3.删除
ul.removeChild(h3);
// h3.remove();
// 4. 遍历查询
console.log(ul.children);
//获取子元素的数量
// console.log(ul.children.length);
//推荐使用已下方法获取子元素数量
console.log(ul.childElementCount);
//获取第一个子元素
console.log(ul.firstElementChild);
//已下方法会取出空白节点,不推荐使用
// console.log(ul.firstChild);
console.log(ul.lastElementChild);
//获取父节点
// console.log(h3.parentElement);
console.log(document.querySelector(".item").parentElement);
//获取前一个兄弟
console.log(document.querySelector("#list li:nth-of-type(9)").previousElementSibling.innerHTML);
//获取后一个兄弟
console.log(document.querySelector("#list li:nth-of-type(9)").nextElementSibling.innerHTML);
</script>
总结:
//新增子元素(最下面)
ul.appendChild(li);
//插入子元素到指定位置
ul.insertAdjacentElement("afterbegin",li);
ul.insertAdjacentHTML("afterbegin","<li>itme test</li>");
更新或者替换元素
2.1 在子元素上调用使用旧值.replaceWith(新值)
document.querySelector("li:nth-of-type(3)").replaceWith(h3);
2.2 在父元素上调用使用 `父元素.replaceChild(新值,旧值)`
ul.replaceChild(h3, document.querySelector("ul > li:last-of-type"));
方法一:
父元素.removeChild(需要删除的子元素);
方法二:
子元素.remove();
console.log(ul.children);
//获取子元素的数量
// console.log(ul.children.length);
//推荐使用已下方法获取子元素数量
console.log(ul.childElementCount);
//获取第一个子元素
console.log(ul.firstElementChild);
//已下方法会取出空白节点,不推荐使用
// console.log(ul.firstChild);
console.log(ul.lastElementChild);
//获取父节点
// console.log(h3.parentElement);
console.log(document.querySelector(".item").parentElement);
//获取前一个兄弟
console.log(document.querySelector("#list li:nth-of-type(9)").previousElementSibling.innerHTML);
//获取后一个兄弟
console.log(document.querySelector("#list li:nth-of-type(9)").nextElementSibling.innerHTML);
神秘的js,似乎也很可爱。继续找寻它的可爱之处。