Bootstrap

2024-7-6-Js面向对象

一.对象是什么

1.对象是单个物体的抽象
2.对象是一个容器,封装的属性和方法
3.对象是无序的  特点   => 对数组去重

二.面向对象

1.对象过程式代码的高度封装,目的是提高效率和可维护性  => 面向对象
2.面向对象的特征     =>   封装性 ,继承性, 多态性
3.面向对象不是面向过程的代替 ,而是面向过程的封装

三创建对象 => 四种方式

1.字面量创建函数

let obj ={ name:"obj"}

2.通过内置的构造函数创建对象

let obj_one = new Object()
obj_one.name ="旺财"
console.log(obj_one)

3.通过构造函数创建对象

function Cat(name){
	this.name = name
}
let cat = new Cat("小黑")
console.log(cat)
console.log(cat.name)     //  =>  获取name的值

4.通过工厂函数创建

function Demo(name){
	let demo_list = new Object()
	demo_list.name = name
	return demo_list
}
let demo1 = new Demo("小黑")
console.log(demo1.name)

四.认识constructor => constructor是什么

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>



//constructor: 构造器,构造者,构造函数
//任何对象都有constructor属性,实例化对象的constructor的属性指向构造函数 ****
//DOM对象 => Bom对象 => 自定义对象 => 内置对象 => 数组 =>  函数   => 对象 ****
//
function Cat2(name, color) {
	this.name = name
	this.color = color
}
let Cat3 = new Cat2('wq', 'ss')
console.log(Cat3);
console.log(history.constructor);     // =>  History() { [native code] }
console.log(new Date().constructor);  // =>  Date() { [native code] }
//判断数据类型
let a = 10
let b = '123'
console.log(a.constructor);
console.log(a.constructor == Number); // =>  Number() { [native code] }
console.log(b.constructor);           // =>  String() { [native code] }


  </script>

</body>

</html>

五.原型prototype 的作用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
/*
一.原型prototype 的作用
1.节省内存空间
2.实现数据共享

二.构造函数,实例,原型三者之间的关系
1.任何函数(不包箭头函数)都有prototype属性,它本身是一个对象
2.构造函数也是函数,也有prototype属性,我们称之为  =>  原型  == 只有构造函数上的prototype称之为原型
3.prototype上的属性和方法可以被实例化对象所继承
4.任何对象都有constructor属性,实例化对象的constructor属性指向构造函数
5.原型也是对象也有constructor属性,原型的constructor属性指向构造函数
6.实例化对象上面有一个 __proto__  他是一个指针,它指向构造函数的原型
三.this 指向:
实例化对象的调用原型上的方法,this指向实例化对象
构造函数原型直接调用方法,this指向构造函数原型
除箭头函数外this指向调用它的地方
箭头函数this指向声明它的地方 

四.构造函数也是函数,也有prototype属性,我们称之为  =>原型  == 只有构造函数上的prototype称之为原型

*/

function fn() {}
console.dir(fn);            //=> fn()
console.log(fn.prototype);  //=> Object()
//2.构造函数也是函数,也有prototype属性,我们称之为  =>原型  == 只有构造函数上的prototype称之为原型
function Car(name) {
	this.name = name
}
console.log(Car.prototype);
//3.
Car.prototype.color = 'red'
Car.prototype.play = function () {
	console.log(this);
	console.log('可以飞');
}
let dome = new Car('小黑')
let dome1 = new Car('狗')
console.log(dome);
console.log(dome.color);
console.log(dome1);
console.log(dome1.color);
console.log(dome.__proto__);
console.log();
  </script>
</body>

</html>

六.实例化对象的查找规则

<script>
/*
1.先在自身对象上查找属性和方法,如果自身有则直接使用  本身如果没有,在原型上面进行查找,依次向下查找,如果都没有打印undefined或者报错
2.字面量创建原型:获取不到,地址不一样
*/
 

    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    Person.prototype.size = '1000'
    Person.prototype.color = 'red'
    console.log(car.size);
    console.log(car.color);
    let car = new Person('张三', 18);
    Person.prototype = {
      constructor: Person,
      color: 'red',
      size: '1000',
    }
    console.log(car);
    console.log(Person.prototype.color);
    console.log(Person.prototype.size)
    console.log(car.name)
    console.log(car.age)
</script>

七.改变this指向的方法 => cell() => apply => bind =>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>重点</title>
</head>

<body>
  <script>
    //改变this 指向的方法(重点)
    /*
    cell()  =>1.可以进行函数的调用
              2.可以改变this指向,如果没有参数this指向window
              3.可以改变this指向,如果有一个参数this指向该参数
              4.可以改变this指向,如果有多个参数this指向第一个参数,其余的数是参数列表
    apply() =>1.可以进行函数的调用
              2.可以改变this指向,如果没有参数this指向window
              3.可以改变this指向,如果有一个参数this指向该参数
              4.可以改变this指向,如果有多个参数this指向第一个参数,其余的参数必须是数组参数列表
    bind()  =>1.不可以进行函数的调用
              2.可以改变this指向,如果没有参数this指向window
              3.可以改变this指向,如果有一个参数this指向该参数
    */
    //箭头函数的this不可以改变 但是有的可以调用
function fn() {
	console.log('无所事事');
}
fn()         //=>无所事事
fn.call()    //=>无所事事
fn.apply()   //=>无所事事
// fn.bind()    //=>报错 不可以进行函数的调用



var obj = {
	name: '小黑',
	age: 18,
	gatName: function (x, y, z) {
	console.log(x, y, z);   // 1 2 3
	console.log(this);      // 通过call和apply指向obj_1这个对象  => {set: '年', name: '我来了'}
	console.log(this.name); // this指向改了这里打印undefined 因为指向的对象里没有name属性和值
}.bind()
}
var obj_1 = {
	set: "年",
	name: "我来了",
}
// var obj_2 = {
//   // set: 1,
//   set: '1',
// }
console.log(obj.name); //  =>   小黑
console.log(obj.age);  //  =>   18
obj.gatName.call(obj_1, 1, 2, 3)    // =>  {set: '年', name: '我来了'}  1,2,3   
obj.gatName.apply(obj_1, [1, 2, 3]) // =>  {set: '年', name: '我来了'}  1,2,3
  </script>
</body>

</html>

八.闭包和闭包之锁住变量

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button>我是0</button>
  <script>
//闭包:定义在一个函数内的函数
//闭包在作用就是把父作用域成为永恒作用域
//作用
//1.可以访问父函数的变量
function add() {
	var name = 'add'
	function addNum() {
		console.log(name);  //=>当前作用域没有name 往上个作用域找name 有就打印 没有就继续找
	}
	addNum()
}
add()
//2.可以锁住父函数中的变量
var btn = document.getElementsByTagName('button')[0]
btn.onclick = function () {
  var count = 0
  return function () {
    count++
    console.log(this);
    console.log(count);
    this.innerHTML = `我是${count}`
  }
}()
</script>
<script>
var age = 18
function fn() {
	console.log('我是谁');
	var str = '字符串'   //局部变量
}
fn()
// console.log(str);  // => 报错 str is not defined 
</script>
<script>
//1.可以访问父函数的变量
function add() {
	var name = 'add'
	function addNum() {
 	console.log(name);  //=>当前作用域没有name 往上个作用域找name 有就打印 没有就继续找
}
addNum()
}
add()
</script>
<script>
    //闭包: this指向 预解析  作用域
    var name = 'win'
    var obj = {
      name: 'obj',
      getName: function () {
        //1.
        console.log(name);        //=> 1.win  2.name(){}
        console.log(this.name);   //=> 2.obj  2.obj
        //3.
        var name1 = 'demo'
        //2.
        function name() {
          console.log(name); // f()
          console.log(this.name); //win
        }
        name()
        console.log(name1);   //=3. => demo
        //4.
        return function () {
          console.log(name);         // =>  5.name(){}
          console.log(this.name);    // =>  5.win
        }
      }
    }
    obj.getName()
    // 5.
    obj.getName()()
</script>
<script>
var x = 10
function fn(x) {
	var x;
	x = 20;
	console.log(x);    // => 20
}
fn(2)
console.log(x);      // => 10
</script>
</body>

</html>
;