js面向对象,函数。

对象的创建方式

1.1字面量方式
var obj = {}
1.2普通模式
		var Person=new Object()
        Person.name='yhb'
        Person.age=20
        Person.speak=function(){
        console.log('hello');
        }
        console.log(Person);

缺点:

  • 因为是基于 Object 基类创建,所以无法获知对象的具体类型
  • 初始化成员非常麻烦
1.3构造函数方式
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>创建自定义的构建函数(创建对象 )</title>
		<script type="text/javascript">
			function Person(name,age,job){
				this.name=name;
				this.age=age;
				this.job=job;
			}
//				第一种写法:
				var person=new Person('张三',23,'软件开发');
				alert('姓名为:' person.name ',年龄为:' person.age ',职位是:' person.job);
//				第二种写法:
				var person1=new Person();
				person1.name='王五';
				person1.age=20;
				person1.job='软件技术系';
				alert('姓名为:' person1.name ',年龄为:' person1.age ',职位为:' person1.job);
		</script>
	</head>
	<body>
	</body>
</html>


缺点:每个函数都会开辟一块新的内存,造成内存浪费

实例化对象的原型链和构造函数的原型链

20170303183502719.png

易错点:
(1)p1是手动创建的,没有constructor属性,p1.constructor是访问的Person.prototype上的constructor属性;
(2)Function是自己创建的自己,Function.constructor指向自己;
(3)Object对象是Function创建的;
(4)每个构造函数、普通函数和Function都有自己的prototype属性;
(5)Function.proto指向Object.prototype,Object.prototype的proto指向null

1.1.proto_和prototype的区别:

prototype属性是一个静态属性,

_proto_属性是一个实例属性。

prototype表示类的原型对象,_proto_表示原型对象中定义的内部属性[prototype]的值。

类的每一个实例都有一个_proto_属性,用于引用创建它的构造方法的prototype属性,也就是该类的原型对象,即存在如下等式:(new Array(“abc”)).proto===Array.prototype (Array(“abc”)为Array的实例)

关于protohe prototype的几个概念

  • 构造函数有一个原型对象,通过 prototype 获取
  • 基于构造函数创建对象后,每个对象都有一个私有的 proto 属性,指向兑现的构造函数的原型对象
  • 基于上面两点,构造函数 prototype 属性与对象的 proto 属性指向的是同一个对象

__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

2.2 constructor构造函数

对象原型( proto)和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。

QQ截图20201221195149.png

<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>
        function Car(brand){
            this.brand=brand
        }
        Car.prototype={
            //原型对象重新赋值
            constructor:Car,
            drive:function(){
                console.log("drive");
            },
            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>
</body>
</html>

constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

2.4构造函数实例和原型对象三角关系

  • 构造函数的prototype属性指向了构造函数原型对象
  • 实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象
  • 构造函数的原型对象的constructor属性指向了构造函数

20201220222939.png

2.6原型对象中this指向

构造函数中的this和原型对象的this,都指向我们new出来的实例对象

QQ截图20201221195821.png

<!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>
        /**
         * 1)在构造函数中,this指代的是创建的构造函数的对象实例
         * 2)在构造函数的原型对象中,this同样指代的是创建的构造函数的对象实例
         */
        function Car(bran){
            this.brand=bran
            console.log(this);
        }
        Car.prototype.run=function(){
            console.log(this);
        }
        var c1=new Car("MAD")
        var c2=new Car("PHP") 
        c1.run()
        c2.run()
    </script>
</body>
</html>

call方法调用:

  • call 可以调用函数
  • call 可以修改this的指向,使用call()的时候 参数一是修改后的this指向,参数2,参数3…使用逗号隔开连接

QQ截图20201221200048.png

<!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>
        function Person(name,sex,add){
            this.name=name
            this.sex=sex
            this.add=add
        }
        function Chinese(name,sex,add,hukou){
            Person.call(this,name,sex,add)   //调用继承Person的指向对象
            this.hukou=hukou
        }
        var c1=new Chinese('ms','nan',18,'beijing')
        console.log(c1)
    </script>
</body>
</html>

1.1.proto_和prototype的区别:

prototype属性是一个静态属性,

_proto_属性是一个实例属性。

prototype表示类的原型对象,_proto_表示原型对象中定义的内部属性[prototype]的值。

类的每一个实例都有一个_proto_属性,用于引用创建它的构造方法的prototype属性,也就是该类的原型对象,即存在如下等式:(new Array(“abc”)).proto===Array.prototype (Array(“abc”)为Array的实例)

实例化对象的原型链和构造函数的原型链

易错点:
(1)p1是手动创建的,没有constructor属性,p1.constructor是访问的Person.prototype上的constructor属性;
(2)Function是自己创建的自己,Function.constructor指向自己;
(3)Object对象是Function创建的;
(4)每个构造函数、普通函数和Function都有自己的prototype属性;
(5)Function.proto指向Object.prototype,Object.prototype的proto指向null

关于protohe prototype的几个概念

  • 构造函数有一个原型对象,通过 prototype 获取
  • 基于构造函数创建对象后,每个对象都有一个私有的 proto 属性,指向兑现的构造函数的原型对象
  • 基于上面两点,构造函数 prototype 属性与对象的 proto 属性指向的是同一个对象

__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

call方法调用:

  • call 可以调用函数
  • call 可以修改this的指向,使用call()的时候 参数一是修改后的this指向,参数2,参数3…使用逗号隔开连接
    QQ截图20201223083743.png
<!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>
        function Person(name,sex,add){
            this.name=name
            this.sex=sex
            this.add=add
        }
        function Chinese(name,sex,add,hukou){
            Person.call(this,name,sex,add)   //调用继承Person的指向对象
            this.hukou=hukou
        }
        var c1=new Chinese('ms','nan',18,'beijing')
        console.log(c1)
    </script>
</body>
</html>

4.1数组方法foreach遍历数组

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

4.2数组方法filter过滤数组

QQ截图20201222162918.png

    <script>
        var arr = [21, 38, 13, 50, 13, 17];
        var newArr = arr.filter(function(value, index,array) {
            //参数一是:数组元素
            //参数二是:数组元素的索引
            //参数三是:当前的数组
            return value >= 20;
        });
        console.log(newArr);//[66,88] //返回值是一个新数组
    </script>

4.3数组方法some

QQ截图20201222163243.png

some 查找数组中是否有满足条件的元素 
 var arr = [10, 30, 4];
 var flag = arr.some(function(value,index,array) {
    //参数一是:数组元素
     //参数二是:数组元素的索引
     //参数三是:当前的数组
     return value < 3;
  });
console.log(flag);//false返回值是布尔值,只要查找到满足条件的一个元素就立马终止循环

4.4筛选商品案例

1.定义数组对象

var data = [{
            id: 1,
            title: '小米',
            price: 3999
        }, {
            id: 2,
            title: 'oppo',
            price: 999
        }, {
            id: 3,
            title: '荣耀',
            price: 1299
        }, {
            id: 4,
            title: '华为',
            price: 1999
        }, {
            id: 5,
            title: '小米',
            price: 3999
        }, {
            id: 6,
            title: 'oppo',
            price: 999
        }, {
            id: 7,
            title: '荣耀',
            price: 1299
        }, {
            id: 8,
            title: '华为',
            price: 1999
        },];

2.使用forEach遍历数据并渲染到页面中

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)
            })
        }

根据价格筛选数据

  1. 获取到搜索按钮并为其绑定点击事件
/** 商品筛选功能
         * 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')

3.筛选信息

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)
        })

5.项目演示:

1.gif

4.5 some和forEach区别

  • 如果查询数组中唯一的元素, 用some方法更合适,在some 里面 遇到 return true 就是终止遍历 迭代效率更高
  • 在forEach 里面 return 不会终止迭代

some和filter和foreach之间的关系:

  • filter():返回一个符合func条件的元素数组。筛选条件,把数组符合条件的放在新的数组里面返回。新数组和原来的数组长度不一定一样。
  • some():返回一个boolean,判断是否有元素是否符合func条件。数组里面所有的元素有一个符合条件就返回true。
  • every():返回一个boolean,判断每个元素是否符合func条件。数组里面所有的元素都符合才返回true。
  • forEach():没有返回值,只是针对每个元素调用func 。循环数组。和for的用法一样的。

4.6 模拟一个String字符串的trim方法,去除字符串两端的空格。

var str = '   hello   '
console.log(str.trim())  //hello 去除两端空格
var str1 = '   he l l o   '
console.log(str.trim())  //he l l o  去除两端空格

4.7 获取对象的属性名

  • 字面量方式创建对象
var person = {
    name: '李白',
    age: 20,
    gender: '男',
    address: '北京'
}
var result = Object.keys(person)
console.log(result);
  • 构造函数创建对象
function Person(name,age){
    this.name=name
    this.age=age
}
var person = new Person('杜甫', 18)
var result = Object.keys(person)
console.log(result);
  • 根据类创建对象
class Person {
    constructor(name, age,gender) {
        this.name = name
        this.age = age
        this.gender=gender
    }
}
var person = new Person('杜甫', 18,'女')
var result = Object.keys(person)
console.log(result);

4.8 Object.defineProperty

QQ截图20201222171455.png

const object1 = {};

Object.defineProperty(object1, 'property1', {
  value: 42,
  writable: false
});

object1.property1 = 77;
// throws an error in strict mode

console.log(object1.property1);
// expected output: 42

语法:

Object.defineProperty(obj,prop,descriptor)
  • obj:定义属性的对象。
  • prop:要定义或修改的属性的名称或 symbol 。
  • descriptor:要定义或修改的属性描述符
  • 返回值:被传递给函数的对象
  • 数据描述符:主要用来描述属性的值、是否可以枚举、是否可以更改属性的值、是否可以删除属性
<!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>
        'use strict'
        var obj = {}
        // obj.name='yhb'
        // console.log(obj);
        Object.defineProperty(obj, 'age', {
            value: '18',
            configurable: true, // 属性可以删除
            writable: true, // 属性的值可以更改
            enumerable: true // 属性可以被枚举出来
        })
        console.log(obj);
        // 修改属性的值
        obj.age = 20
        console.log(obj);
        console.log(Object.keys(obj));
        // delete obj.age // 从 obj 对象中删除 age 属性
        // console.log(obj);

        Object.defineProperty(obj, 'gender', {
            get: function () {
                return 'hello'
            },
            set: function (newValue) {
                console.log(newValue);
            }
        })
        console.log(obj.gender);
        obj.gender='女'
    </script>
</body>

</html>

QQ截图20201222172420.png

这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):

  • configurable

    当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 默认为 false

  • enumerable

    当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。 默认为 false

数据描述符还具有以下可选键值:

  • value

    该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 默认为 undefined

  • writable

    当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。 默认为 false

单击绑定案例:

8.gif

<!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>
    <div id="app">
        <p>{{title}}</p>
    </div>
    <button>修改</button>
    <script src="/vue.js"></script>
    <script>
        
        obj.title='添加'
        document.querySelector('button').addEventListener('click',function(){
            obj.title='显示'
        })
    </script>
</body>

</html>
var obj = {}
var nodes = document.querySelector('#app').children
var title_node = null
console.log(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
    }
})
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值