批改状态:合格
老师批语:
任何一个函数都有一个原型属性:prototype,该属性是一个指针,指向一个对象,该对象称之为原型对象(可以使用这个原型对象帮助我们在js中实现继承)
原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。
调用构造函数实例化对象,都拥有一个内部属性,指向原型对象。其实例对象能够访问原型对象上的所有属性和方法
简言之:每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数
//任何一个函数都有一个原型属性:prototypefunction 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);//headconsole.log(document.head);//bodyconsole.log(document.body);//titleconsole.log(document.title);//formsconsole.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]。一组快捷键需要记下
//htmlconsole.log(document.documentElement);//headconsole.log(document.head);//bodyconsole.log(document.body);//titleconsole.log(document.title);//formsconsole.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,似乎也很可爱。继续找寻它的可爱之处。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号