面向对象知识点

面向对象中的各个方法

1. __proto__

  • __proto__是构造函数中的一个原型对象,通过 prototype 获取
  • 基于构造函数创建对象后,每个对象都有一个私有的 proto 属性,指向兑现构造函数的原型对象
  • 基于上面两点,构造函数 prototype 属性与对象 proto 属性指向的是同一个对象
<script>
    function Car(brand){
				this.brand=brand //实例属性
			}
			console.log(Car.prototype);
			var c1 = new Car();
			console.log(c1.__proto__);
			var c2 = new Car();
			// console.log(c2.__proto__);
			console.log(Object.getPrototypeOf(c2));//Object.getPrototypeOf() 方法返回指定对象的原型
			console.log(c1.__proto__ === c2.__proto__); // 指向同一个内存地址
</script>

2. call

  • call 可以调用函数

  • 还可以修改 this 的指向,call 方法第一个参数,用于替代函数中的 this ,第二参数开始,才是参数列表,使用 call() 的时候,参数一是修改后的 this 指向,参数2,参数3,参数…使用逗号隔开链接

  • 继承的主要目的是代码重用

  • 前面使用 class 方式创建的类,可以非常轻松的实现继承,就跟其他的面向对象编程语言一样,如 c++ ,Java 等

  • class 语法只是 js 中的一种语法糖,其本质还是使用了基于原型的构造函数

  • 使用 call 方法,就可以实现构造函数之间的继承

    <script>
        function Father(name,age){
    				this.name = name
    				this.age = age
    			}
    			function Son(name,age){
    				Father.call(this,name,age)
    			}
    			var s1 = new Son('李白',53)
    			var s2 = new Son('杜甫',50)
    			console.log(s1)
    			console.log(s2)
    			console.log('---------------------------')
    			function Father(name,age,height,weight,gender){
    				this.name = name
    				this.age = age
    				this.height = height
    				this.weight = weight
    				this.gender = gender
    			}
    			function Chinese(name,age,height,weight,gender,hukou){
    				// this.name = name
    				// this.age = age
    				// this.hukou = hukou
    				Father.call(this,name,age,height,weight,gender)
    				this.hukou =hukou
    			}
    			var c1 =new Chinese('ysx',18,170,88,'男','河北保定')
    			console.log(c1)
    </script>
    

3. constructor

原型对象通过 constructor 指回构造函数

  • 对象原型 (__proto__) 和 构造函数 (prototype) 原型函数里面都有一个 constructor 属性,constructor 我们称为构造函数,因为它指回构造函数的本身
<script>
    function Car(brand) {
				this.brand = brand //实例属性
			}
			// Car.prototype.drive = function() {
			// 	console.log('骑着我的小毛驴')
			// }
			// Car.prototype.start = function() {
			// 	console.log('start')
			// }
			// Car.prototype.stop = function() {
			// 	console.log('stop')
			// }
			// Car.prototype.run = function() {
			// 	console.log('run')
			// }
			Car.prototype = {
				/*只这样写会少一个方法,因为这种方法只是重写,没有回调指向,
				* 所以我们要用constructor方法回调
				* */
				constructor:Car,
				drive:function(){
					console.log('骑着我的小毛驴')
				},
				start:function(){
					console.log('start')
				},
				stop:function(){
					console.log('stop')
				},
				run:function(){
					console.log('run')
				}
			}
			console.log(Car.prototype);
			var c1 = new Car()
			c1.drive()
</script>

4.原型对象

  • 每一个构造函数都有一个 prototype 属性,此属性的值是一个对象,这个对象叫做当前构造函数的原型对象
  • 原型对象上的所有属性和方法,构造函数中也会拥有
  • 所以将方法定义到原型对象上,可以让多个构造函数的对象 (p1 p2) 共享一个方法,节省内存空间
<script>
    function Preson(name,age){
		this.name = name
		this.age = age
		this.run = function(){
				console.log('run')
		}
	}
    Preson.prototype.does=function(){
			console.log('hello world')
	}
	console.log(Preson.prototype);
	var p1 = new Preson('金菱玉','100000');
	p1.does()
	var p2 = new Preson('武陵仁','1000');
	p2.does()
	console.log(p1.does === p2.does)
	console.log(p1.run === p2.run)
</script>

5.语法糖

  • 通过构造函数的形式创建对象,是 JS 中最本质的创建对象的方式
  • 通过 class 的方式创建对象,只是 JS 中的语法糖
  • 开发中可以放心使用 class 方法创建对象,可以试试用插件将其编译成 ESS 语法,保证兼容性
<script>
    function Person(name,age){
		this.name=name
		this.age = age
	}
	var p1 = new Person('yhb',18);
	var p2 = new Person('hapi',19);
	console.log(p1);
	console.log(p2);
			 
	 /*
	 * 语法糖
	 */
	class car{
		constructor(name,born) {
			this.name = name
			this.born = born
		}
	}
	var h = new car('五岳',1988);
	console.log(h);
</script>

6. 类的继承 class

  • super 就代表了父类的构造函数

    <script>
        class Dog{
            constructor(name,age){
                this.name = name
                this.age = age
            }
            speak(){
                console.log('汪汪汪')
            }
        }
        class Hshiqi extends Dog{
            constructor(name,age,levl) {
                // super  就代表了父类的构造函数
    		    super(name,age)
    		    this.levl = levl
            }
            does(){
                console.log('拆家')
            }
            speak(){
                console.log('嗷嗷嗷')
            }
        }
        var h = new Hshiqi('哈皮',18,8)
        // h.speak()
        // h.does()
        console.log(h)
    </script>
    

7.静态成员

  • 构造函数中成员分为两种: 实例成员 和 静态成员,我们下面以属性为例为例
  • 通过 new 关键字创建的就是构造函数中的实例
  • 所谓的实例属性就是只能同各国构造函数的实例访问
  • 静态属性只能通过类名,属性名称的方式访问: 使用类名.属性访问 访问
  • 静态成员是在构造函数本身上添加的成员,与具体的对象无关
<script>
    function Car(brand){
        this.brand=brand //实例属性
       //Car.count == undefined还可以写成 ! 形式
       if(!Car.count){
           Car.count = 0 //静态属性 static
       }
       Car.count++
     }
     var c1 = new Car('五菱之光');
     console.log(Car.count)
     var c2 = new Car('奔驰');
     console.log(Car.count)
     var c3 = new Car('劳斯莱斯');
     console.log(Car.count)
     // console.log(c1.brand);
     // console.log(c1.count);
</script>

8.关系

QQ图片20201222171414.png

  • 任何对象都有原型对象,也就是 prototype 属性,任何原型对象也是一个对象,该对象就有 __proto__ 属性,这样一层一层往上找,就形成了一条链,我们称此为原型链
  • 查找机制:
    • 当访问一个对象的属性 (包括方法) 时,首先查找这个对象自身有没有该属性
    • 如果没有就查找它的原型 (也就是 __proto__ 指向的 prototype 原型对象)
    • 如果还没有就查找原型对象的原型 (Object 的原型对象)
    • 以此类推一直找到Obedct 为止 (null)
    • __proto__ 对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
<script>
    function Car(brand) {
		this.brand = brand //实例属性
	}
	// //构造函数的 prototype 属性指向原型对象
	// console.log(Car.prototype)
	// // 原型对象的 constructor 属性指向构造函数
	// console.log(Car.prototype.constructor)
	// var c1=new Car()
	// console.log(c1.__proto__.__proto__)
	Car.prototype.__proto__.run = function() {
			console.log('run')
	}
	var c1 = new Car()
	c1.run()
</script>

9.this

  • 当在全局创建一个 this 指向时,他的指向位置就是 Window
  • 在创造函数中创建一个 this 指向时,他的指向是我们创建的构造函数中的对象实例
  • 在构造函数的原型对象中, this 同样指代构造函数中的对象实例
<script>
    // function f1(){
		// 	console.log(this)
	// }
	// f1()
	function Car(brand){
		this.brand = brand;
		console.log(this);
	}
	Car.prototype.run=function(){
		console.log(this);
	}
	var c1 = new Car('五菱宏光');
	var c2 = new Car('长城皮卡');
	console.log(c1 === c2);
	c1.run()
	c2.run()
</script>

10.数组

<script>
    var arr = new Array()
	console.log(arr.__proto__);
	console.log(Array.prototype);
    var arr1=[]
    console.log(arr1.__proto__);
    function sum(arr){
        sdadada
	}
	sum(arr)
</script>

11. forEach 遍历数组

  • forEach 相当于数组遍历的 for循环 没有返回值
<script>
    arr.forEach(function(value, index, array) {
		参数一是:数组元素
		参数二是:数组元素的索引
		参数三是:当前的数组
	})
</script>

案例:

<script>
    var arr = [1, 3, 4, 5, 6]

    arr.forEach(function(currentValue,index,arr){
        console.log(currentValue,index,arr);
	})
    
    
    Array.prototype.sum=function(){
		//console.log(this);
		var sum=0;
		this.forEach(function(item){
			// console.log(item);
				sum+=item
		})
			return sum
	}
	console.log(Array.prototype);
			
	var arr=[2,3,4]
	// arr.sum()
	console.log(arr.sum());
	console.log([4,5,6].sum());
</script>

12.some

  • some 查找数组中是否有满足条件的元素
  • some的各个参数:
    • 参数1:数组元素
    • 参数2:数组元素的索引
    • 参数3:当前的数组
  • 返回值 : 数组中至少一个元素通过回调函数的测试就会返回 true,所有元素都没通过回调函数的测试返回值才会为 false
  • some 和 forEach的区别:
    • 如果查询数组中唯一的元素, 用some方法更合适,在some 里面 遇到 return true 就是终止遍历 迭代效率更高
    • 在forEach 里面 return 不会终止迭代
<script>
    var arr = [1, 3, 4, 5, 6]
	var result = arr.some(function(value, index, arr){
			return value > 3
     })
	 console.log(result)
</script>

13. filter

filter截取数组函数

  • forEach 是循环数组,filter 返回值是一个新的、由通过测试的元素组成的数组,如果没有任何数组通过测试,则返回空数组
<script>
    var arr = [1, 3, 4, 5, 6]
    var result = arr.filter(function(item, index, arr){
			return item > 3
	})
	console.log(result)
</script>

14. find 和 findIndex

  • find() 方法 返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined
  • findIndex() 方法 返回数组中满足提供的测试函数的第一个元素的索引。如果没有找到对应元素则返回-1
<script>
    var arr = [1, 3, 4, 5, 6]
	//var arr = [1, 3, 2]
	var result = arr.find(function(value, index, arr){
        return value > 3
	})
	console.log(result)
			 
	var result = arr.findIndex(function(value, index, arr){
        return value > 3
	})
	console.log(result)
</script>

15.筛选

筛选案例

  • 页面加载时加载所有商品
  • 用户输入了哪些数据,就按照这些条件进行筛选
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			.box{
				margin: 10px 300px;
			}
			.header{
				margin-bottom: 10px;
			}
			table{
				border: 1px solid #000;
				width: 800px;
				border-collapse: collapse;
				text-align: center;
			}
			th,td{
				border: 1px solid #000;
				padding: 5px 10px;
			}
		</style>
	</head>
	<body>
		<div class="box">
			<div class="header">
				<label>最低价格</label>
				<input type="text" id="start_price" />
				<label>最高价格</label>
				<input type="text" id="end_price" />
				<label>商品名称</label>
				<input type="text" id="title" />
				<button id="btn_filter">筛选</button>
			</div>
			<table>
				<thead>
					<tr>
						<th>编号</th>
						<th>商品名称</th>
						<th>价格</th>
					</tr>
				</thead>
				<tbody>

				</tbody>
			</table>
		</div>
		<script>
			/**
			 * 1)页面加载时加载所有商品
			 * 2)用户输入了哪些数据,就按照这些条件进行筛选
			 * */
			var btn_filter = document.querySelector('#btn_filter');
			var start_price = document.querySelector('#start_price');
			var end_price = document.querySelector('#end_price');
			var title = document.querySelector('#title');

			var data = [{
				id: '001',
				title: '小米10',
				price: 3999
			}, {
				id: '002',
				title: '小米8',
				price: 2099
			}, {
				id: '003',
				title: '小米7',
				price: 1999
			}, {
				id: '004',
				title: 'iPhone11',
				price: 5666
			}, {
				id: '005',
				title: 'iPhone8',
				price: 3333
			}, {
				id: '006',
				title: 'iPhone8',
				price: 7566
			}, {
				id: '007',
				title: 'oppo',
				price: 1500
			}, {
				id: '008',
				title: 'vivo',
				price: 1500
			}, {
				id: '009',
				title: '华为',
				price: 820
			}, {
				id: '010',
				title: '锤子',
				price: 903
			}, ];
			setData(data)

			function setData(pro_data) {
				document.querySelector('tbody').innerHTML = ''
				pro_data.forEach(function(item) {
					var tr =
						`
					 <tr>
					     <td>${item.id}</td>
						 <td>${item.title}</td>
						 <td>${item.price}</td>
					 </tr>
					 `
					document.querySelector('tbody').insertAdjacentHTML('beforeend', tr)
				})
			}
			btn_filter.addEventListener('click', function() {
				var newData = data.filter(function(item) {

					var new_start_price = start_price.value != '' ? start_price.value : 0;
					var new_end_price = end_price.value != '' ? end_price.value : Infinity;
					var new_title = title.value != '' ? title.value : item.title;

					return item.price >= new_start_price && item.price <= new_end_price && item.title == new_title
				})
				console.log(newData)
				setData(newData)
			})
		</script>
	</body>
</html>

16. trim

trim方法去除字符串两端的空格

<script>
	var str = '   hello   '
	console.log(str.trim()) //去除两端的空格
</script>

17.获取对象属性名称

  • Object.keys(对象) 获取到当前对象中的属性名 ,返回值是一个数组
  • Object.keys 获取的是对象中的是属性,而不是类或者构造函数
  • 他一般很少用,但是想自己编写库或者框架,是需要的
<script>
	 var person = {
		 name:'yhb',
		 age:20
	 }
	 var keys=Object.keys(person)
	 console.log(keys);
	 
	 //使用构造函数创建对象
	 function Car(){
		 this.name='asjkda'
		 this.gender='男'
	 }
	 var c1=new Car()
	 console.log(Object.keys(c1))
	 
	 //使用class方法
	 class Dog{
		 constructor(name,age) {
		     this.name=name
			 this.age=age
		 }
	 }
	 var d1=new Dog()
	 console.log(Object.keys(d1))
</script>

18.Object.defineProperty()

  • bject.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
  • Object.defineProperty() 方法 应当直接在构造器对象上调用,而不是在任意一个 Object 类型的实例上调用。
  • Object.defineProperty(obj, prop, descriptor) 各个参数意义:
    • obj:要定义属性的对象。
    • prop:要定义或修改的属性的名称或 Symbol
    • descriptor:要定义或修改的属性描述符
  • 重点是 descriptor 属性
  • 数据描述符:主要用来描述属性的值、是否可以枚举、是否可以更改属性的值、是否可以删除属性
  • 'use strict' 严谨模式
<script>
	 'use strict' //严谨模式
	 var obj={}
	 // obj.name='yhb'
	 // console.log(obj);
	 Object.defineProperty(obj,'age',{
		 value:'18', //在给对象添加属性时,我们默认属性为不可删,不可改
		 configurable:true ,//设置 configurable 属性 ,并把值设置为true ,属性可以删除
		 writable:true ,//设置 writable 属性 ,并设为true , 属性的值可以修改
		 enumerable:true //属性可以被枚举(列)出来
	 })
	 console.log(obj)
	 obj.age = 20 //修改 age 的值
	 //delete obj.age //从 obj 对象中删除 age 属性
	 console.log(obj);
	 console.log(Object.keys(obj));
	 
	 
	 Object.defineProperty(obj,'gender',{
		 get : function(){
			 return 'hello' //返回值作为我们的属性值
		 },
		 set:function(newValue) {
			 console.log(newValue); //存取描述
		 }
	 })
	 console.log(obj.gender);
	 obj.gender='女'
</script>

19.数组绑定

单向数组绑定

html:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>单向数组绑定</title>
	</head>
	<body>
		<div id="app">
			<p>{{title}}</p>
		</div>
		<button>修改</button>
		<script src="./vue.js"></script>
		<script>
			obj.title='sss'
			document.querySelector('button').addEventListener('click',function(){
				obj.title='你好'
			})
		</script>
	</body>
</html>

vue.js 代码

var obj = {}
var nodes = document.querySelector('#app').children
var title_node = null
console.log(nodes);
//nodes 是伪数组 所以要转型 
Array.from(nodes).forEach(function(item){
	if (item.innerHTML == '{{title}}'){
		title_node = item
	}
})
Object.defineProperty(obj, 'title', {
	set: function(newValue) {
		title_node.innerHTML = newValue
	}
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值